func-y

2.2.3 • Public • Published

Func - y (funk-ee)

Auto-calling render functions.

Features

  • Streams (see below)
  • Promises (see below)
  • HTML safe: Ohoh <sript src="//example.com/script"></script> is all escaped by the write.text() function.
    • Streams can be throw through there too if you don't trust a file.

Usage

Unnamed templates

const myTemplate = require('..') `You can put anything here now.
 
Raw HTML, anything.
 
Including a stream can be done too: ${(env, {file}) => file('file.txt')}.
 
Note that this is an effective shortcut for \`require('fs').createReadStream('file.txt')\`.
 
A stream in a promise from a different source is fine too: ${(env, {net}) => net('https://example.com')}.
 
Note that this is an effective shortcut for
 
\`\`\`javascript
(opts) => new Promise(r => {
  let {URL} = require('url')
  let o = 'string' === typeof opts ? new URL(opts) : opts
  require(o.protocol.slice(0,-1)).request(o, r)
})
\`\`\`
 
. See func-y/writer.js#writeFromNet (34:1) for more details.
 
Promises work too: ${() => new Promise(r => setTimeout(r, 3e3, 'Resolved after 3 seconds'))}.
 
There's other stuff: ${(env, write) => write.all(123, 'Mix and match', Infinity, String.fromCodePoint(0x2026), new Promise(r => setTimeout(r, 2e3, 'with random timing')), () => 'and subfunctions if memory is an issue?')}`
 
module.exports = myTemplate

The above will result in the following array:

[ 'You can put anything here now.\n\nRaw HTML, anything.\n\nIncluding a stream can be done too: ',
  [Function],
  '.\n\nNote that this is an effective shortcut for `require(\'fs\').createReadStream(\'file.txt\')`.\n\nA stream in a promise from a different source is fine too: ',
  [Function],
  '.\n\nNote that this is an effective shortcut for\n\n```javascript\n(opts) => new Promise(r => {\n  let {URL} = require(\'url\')\n  let o = \'string\' === typeof opts ? new URL(opts) : opts\n  require(o.protocol.slice(0,-1)).request(o, r)\n})\n```\n\n. See func-y/writer.js#writeFromNet (34:1) for more details.\n\nPromises work too: ',
  [Function],
  '.\n\nThere\'s other stuff: ',
  [Function] ]

Named templates

For named templates (like this README.md from test/README.js), there are several options:

const README = require('../named')('README.md', 'text/markdown') `# Func - y (funk-ee)
 
Auto-calling render functions.
 
## Features
 
* Streams (see below)
* Promises (see below)
* HTML safe: ${(e, {text}) => text('Ohoh <sript src="//example.com/script"></script>')} is all escaped by the write.text() function.
  * Streams can be throw through there too if you don't trust a file.
 
## Usage
 
### Unnamed templates
 
\`\`\`javascript
${(env, { file }) => file([__dirname, './template.js'])}
\`\`\`
 
The above will result in the following array:
 
\`\`\`javascript
${({ util }) => util.inspect(require('./template.js'), false, 3, false)}
\`\`\`
 
### Named templates
 
For named templates (like this README.md from [\`test/README.js\`](./test/README.js)), there are several options:
 
\`\`\`javascript
${(env, write) => write.file([__dirname, './README.js'])}
\`\`\`
 
Results in a data like this:
 
\`\`\`javascript
${({ util }) => util.inspect(README, false, 4, false)}
\`\`\`
 
${
  (env, write) => write.all(
    write.file([__dirname, 'api.md']),
    '\n\n',
    write.file([__dirname, 'alts.md'])
  )
}`
 
const env = { util: require('util') }
 
README.writeToFile(require('path').join(__dirname, '../README.md'), {
  overwrite: true, env
}).then(console.log, console.error)
README.writeTo(process.stdout, env, false).catch(console.error)
 
 
module.exports = README

Results in a data like this:

{ name: 'README.md',
  type: 'text/markdown',
  template: 
   [ '# Func - y (funk-ee)\n\nAuto-calling render functions.\n\n## Features\n\n* Streams (see below)\n* Promises (see below)\n* HTML safe: ',
     [Function],
     ' is all escaped by the write.text() function.\n  * Streams can be throw through there too if you don\'t trust a file.\n\n## Usage\n\n### Unnamed templates\n\n```javascript\n',
     [Function],
     '\n```\n\nThe above will result in the following array:\n\n```javascript\n',
     [Function],
     '\n```\n\n### Named templates\n\nFor named templates (like this README.md from [`test/README.js`](./test/README.js)), there are several options:\n\n```javascript\n',
     [Function],
     '\n```\n\nResults in a data like this:\n\n```javascript\n',
     [Function],
     '\n```\n\n',
     [Function] ],
  middleware: [Function: middleware],
  createMiddleWare: [Function: createMiddleWare],
  writeTo: [Function: writeTo],
  writeToFile: [Function: writeToFile] }

API

const {template, named, namedMiddleware} = require('func-y')
// require('func-y') === require('func-y').template
let arr = template`
* Text string 
${'other data'} 
${1234e6} 
${() => 'a function'}
${env => env.data}
${({data}) => data}
${(env, write) => write('text and ').then(() => env.aPromise = new Promise(r => setTimeout(r,32, 'a promise')))}
${async env => await env.aPromise}
${(env, write) => write.next(/* err */ /*, data */)}
${
  // etc
  ''
}`
 
let keyed = named('key', 'application/mimetype') `Roughly the same as above.
${() => new Promise(r => setTimeout(r, 1e3, 'Really.'))}
${() => new Promise(r => setTimeout(r, 1e3, 'Seriously.'))}`
 
keyed.writeTo(process.stdout, {/* ...env */}, false) 
// (writable, env, autoclose)
keyed.writeToFile('test.txt', {overwrite: false, encoding: 'utf8'})
// (filename, {...options})
 
// Express ready:
const app = require('express')()
app.use(keyed.createMiddleWare())
 
// can use in different part of the app
 
const sub = require('express')
 
sub.use(namedMiddleware('key'))

and so-on and so-fourth.

See the documents internals in named.js, template.js, writer.js and write-file.js.

Meanwhile, index.js just holds everything together. I think.

Vs Alternatives

func-y will render on-the-fly as an alternative to the collect-and-display of similar systems, such as HyperHTML/ViperHTML and lit-html styles.

First-render is exceedingly fast if the main styles are available.

A simple for await or for (const thing of source) await write(stuff(thing))

It is a streaming based parser/builder, and capable of all of the same things as the Hyper and lit server side renderers are.

It has a set of built in write functions (sequential write.all(data, data, data, ...datas), write.next(err, data), write.text(unsafe_string) and plain write(data)).

It's capable of writing/caching files (less useful with the exception of heavy stuff like markdown/markdown-it).

It handles streams, promises and delays consistently.

Can puke in data from anywhere (including different sites)

It handles all data types (except symbol) in a consistent fashion.

It's fast and (primarily) in-memory.

It's lightweight, and capable of all of the above out-of-the-box (in node).

If looking for a highly interactive DOM, use hyperhtml/viperhtml.

If looking for a simple streaming HTML (or just anything text based) output, use this.

TL;DR it's function based sequential data collection/export with enough extras to be used... basically anywhere.

Package Sidebar

Install

npm i func-y

Weekly Downloads

1

Version

2.2.3

License

GPL-3.0

Last publish

Collaborators

  • zanehannanau