sendscript 0.0.0 → 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ ### Changelog
2
+
3
+ All notable changes to this project will be documented in this file. Dates are displayed in UTC.
4
+
5
+ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
6
+
7
+ #### [v0.0.1](https://github.com/bas080/sendscript/compare/v0.0.0...v0.0.1)
8
+
9
+ - Add square fn to the socket.io example [`8d7cfbd`](https://github.com/bas080/sendscript/commit/8d7cfbddd7933804e7168825cf1e17e792c91fe9)
10
+ - Rename dsl to api [`4a67324`](https://github.com/bas080/sendscript/commit/4a6732456656db743d02c5c35444f93a866d27ec)
11
+ - Move promise only concept to own module [`50adde6`](https://github.com/bas080/sendscript/commit/50adde694b3d23fb025a4ad20dcc83d7bb72b852)
12
+
13
+ #### v0.0.0
14
+
15
+ > 14 September 2023
16
+
17
+ - Initiate project [`2a192b3`](https://github.com/bas080/sendscript/commit/2a192b34e5390ab946b7b77fd299e23180c49f72)
package/README.md CHANGED
@@ -3,11 +3,13 @@
3
3
  Write JS code that you can run on servers, browsers or other clients.
4
4
 
5
5
  [![NPM](https://img.shields.io/npm/v/sendscript?color=blue&style=flat-square)](https://www.npmjs.com/package/sendscript)
6
+ [![100% Code Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?style=flat-square)](#tests)
6
7
  [![Standard Code Style](https://img.shields.io/badge/code_style-standard-brightgreen.svg?style=flat-square)](https://standardjs.com)
7
- [![License](https://img.shields.io/npm/l/sendscript?color=brightgreen&style=flat-square)](./LICENSE)
8
+ [![License](https://img.shields.io/npm/l/sendscript?color=brightgreen&style=flat-square)](./LICENSE.txt)
8
9
 
9
- > SendScript leaves it up to you to choose HTTP, web-sockets or any other method of
10
- > communication between servers and clients that best fits your needs.
10
+ > SendScript leaves it up to you to choose HTTP, web-sockets or any other
11
+ > method of communication between servers and clients that best fits your
12
+ > needs.
11
13
 
12
14
  ## Socket example
13
15
 
@@ -21,17 +23,18 @@ npm install --no-save socket.io socket.io-client
21
23
 
22
24
  ### Module
23
25
 
24
- We write a simple module that only has an add function
26
+ We write a simple module.
25
27
 
26
28
  ```js
27
29
  // ./example/math.mjs
28
30
 
29
31
  export const add = (a, b) => a + b
32
+ export const square = a => a * a
30
33
  ```
31
34
 
32
35
  ### Server
33
36
 
34
- Here a simple module for running a socket.io server that runs SendScript programs.
37
+ Here a socket.io server that runs SendScript programs.
35
38
 
36
39
  ```js
37
40
  // ./example/server.socket.io.mjs
@@ -66,7 +69,7 @@ Now for a client that sends a program to the server.
66
69
  // ./example/client.socket.io.mjs
67
70
 
68
71
  import socketClient from 'socket.io-client'
69
- import dsl from '../dsl.mjs'
72
+ import api from '../api.mjs'
70
73
 
71
74
  const port = process.env.PORT || 3000
72
75
  const client = socketClient(`http://localhost:${port}`)
@@ -81,10 +84,10 @@ const exec = program => {
81
84
  })
82
85
  }
83
86
 
84
- const { add } = dsl(['add'], exec)
87
+ const { add, square } = api(['add', 'square'], exec)
85
88
 
86
89
  console.log(
87
- await add(1, add(add(2, 3), 4))
90
+ await square(add(1, add(add(2, 3), 4)))
88
91
  )
89
92
 
90
93
  process.exit(0)
@@ -102,33 +105,33 @@ node ./example/client.socket.io.mjs
102
105
  pkill sendscript
103
106
  ```
104
107
  ```
105
- 10
108
+ 100
106
109
  ```
107
110
 
108
111
  ## Reference
109
112
 
110
- SendScript is essentially a way to serialize a program to then send over the wire
111
- and execute it somewhere else.
113
+ SendScript is essentially a way to serialize a program to then send over the
114
+ wire and execute it somewhere else.
112
115
 
113
116
  We only have two modules. One that helps you write programs that can be sent
114
117
  over the wire and another for running that program.
115
118
 
116
- ### `sendscript/dsl.mjs`
119
+ ### `sendscript/api.mjs`
117
120
 
118
- The dsl module exports a function that takes two arguments.
121
+ The api module exports a function that takes two arguments.
119
122
 
120
123
  1. The schema, which represents the values that are available.
121
124
  2. The function that will be called with the serializable version of the
122
125
  program.
123
126
 
124
127
  It returns an object that contains functions which are defined in the schema.
125
- These functions are a JavaScript DSL for writing programs that can be sent to
128
+ These functions are a JavaScript API for writing programs that can be sent to
126
129
  a server.
127
130
 
128
131
  ```js
129
- import dsl from './dsl.mjs'
132
+ import api from './api.mjs'
130
133
 
131
- const { add, subtract } = dsl(
134
+ const { add, subtract } = api(
132
135
  ['add', 'subtract'],
133
136
  serializableProgram => sendSomewhereToBeExecuted(serializableProgram)
134
137
  )
@@ -144,7 +147,7 @@ soon as await or `.then` is used.
144
147
  > Notice that you do not have to await the subtract call. You only need to
145
148
  > await when you want to execute the program.
146
149
 
147
- This DSL is composable and wrappable.
150
+ This API is composable and wrappable.
148
151
 
149
152
  ### `sendscript/exec.mjs`
150
153
 
@@ -161,8 +164,8 @@ exec({
161
164
 
162
165
  The array you see here is the LISP that SendScript uses to represent programs.
163
166
 
164
- You could use SendScript without knowing the details of how the LISP works. It is an
165
- implementation detail and might change over time.
167
+ You could use SendScript without knowing the details of how the LISP works. It
168
+ is an implementation detail and might change over time.
166
169
 
167
170
  ## Tests
168
171
 
@@ -173,27 +176,28 @@ npx c8 --100 npm t -- -R classic
173
176
  ```
174
177
  ```
175
178
 
176
- > sendscript@0.0.0 test
179
+ > sendscript@0.0.1 test
177
180
  > tap *.test.mjs --no-cov -R classic
178
181
 
182
+ api.test.mjs .......................................... 5/5
179
183
  curry.test.mjs ........................................ 4/4
180
- dsl.test.mjs .......................................... 5/5
181
- exec.test.mjs ....................................... 15/15
182
- total ............................................... 24/24
184
+ exec.test.mjs ....................................... 16/16
185
+ total ............................................... 25/25
183
186
 
184
- 24 passing (400.194ms)
187
+ 25 passing (406.01ms)
185
188
 
186
189
  ok
187
- -----------|---------|----------|---------|---------|-------------------
188
- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
189
- -----------|---------|----------|---------|---------|-------------------
190
- All files | 100 | 100 | 100 | 100 |
191
- curry.mjs | 100 | 100 | 100 | 100 |
192
- debug.mjs | 100 | 100 | 100 | 100 |
193
- dsl.mjs | 100 | 100 | 100 | 100 |
194
- error.mjs | 100 | 100 | 100 | 100 |
195
- exec.mjs | 100 | 100 | 100 | 100 |
196
- -----------|---------|----------|---------|---------|-------------------
190
+ ------------------|---------|----------|---------|---------|-------------------
191
+ File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
192
+ ------------------|---------|----------|---------|---------|-------------------
193
+ All files | 100 | 100 | 100 | 100 |
194
+ api.mjs | 100 | 100 | 100 | 100 |
195
+ curry.mjs | 100 | 100 | 100 | 100 |
196
+ debug.mjs | 100 | 100 | 100 | 100 |
197
+ error.mjs | 100 | 100 | 100 | 100 |
198
+ exec.mjs | 100 | 100 | 100 | 100 |
199
+ promise-only.mjs | 100 | 100 | 100 | 100 |
200
+ ------------------|---------|----------|---------|---------|-------------------
197
201
  ```
198
202
 
199
203
  ## Formatting
package/README.mz CHANGED
@@ -3,11 +3,13 @@
3
3
  Write JS code that you can run on servers, browsers or other clients.
4
4
 
5
5
  [![NPM](https://img.shields.io/npm/v/sendscript?color=blue&style=flat-square)](https://www.npmjs.com/package/sendscript)
6
+ [![100% Code Coverage](https://img.shields.io/badge/coverage-100%25-brightgreen?style=flat-square)](#tests)
6
7
  [![Standard Code Style](https://img.shields.io/badge/code_style-standard-brightgreen.svg?style=flat-square)](https://standardjs.com)
7
- [![License](https://img.shields.io/npm/l/sendscript?color=brightgreen&style=flat-square)](./LICENSE)
8
+ [![License](https://img.shields.io/npm/l/sendscript?color=brightgreen&style=flat-square)](./LICENSE.txt)
8
9
 
9
- > SendScript leaves it up to you to choose HTTP, web-sockets or any other method of
10
- > communication between servers and clients that best fits your needs.
10
+ > SendScript leaves it up to you to choose HTTP, web-sockets or any other
11
+ > method of communication between servers and clients that best fits your
12
+ > needs.
11
13
 
12
14
  ## Socket example
13
15
 
@@ -21,17 +23,18 @@ npm install --no-save socket.io socket.io-client
21
23
 
22
24
  ### Module
23
25
 
24
- We write a simple module that only has an add function
26
+ We write a simple module.
25
27
 
26
28
  ```js cat - > ./example/math.mjs
27
29
  // ./example/math.mjs
28
30
 
29
31
  export const add = (a, b) => a + b
32
+ export const square = a => a * a
30
33
  ```
31
34
 
32
35
  ### Server
33
36
 
34
- Here a simple module for running a socket.io server that runs SendScript programs.
37
+ Here a socket.io server that runs SendScript programs.
35
38
 
36
39
  ```js cat - > ./example/server.socket.io.mjs
37
40
  // ./example/server.socket.io.mjs
@@ -66,7 +69,7 @@ Now for a client that sends a program to the server.
66
69
  // ./example/client.socket.io.mjs
67
70
 
68
71
  import socketClient from 'socket.io-client'
69
- import dsl from '../dsl.mjs'
72
+ import api from '../api.mjs'
70
73
 
71
74
  const port = process.env.PORT || 3000
72
75
  const client = socketClient(`http://localhost:${port}`)
@@ -81,10 +84,10 @@ const exec = program => {
81
84
  })
82
85
  }
83
86
 
84
- const { add } = dsl(['add'], exec)
87
+ const { add, square } = api(['add', 'square'], exec)
85
88
 
86
89
  console.log(
87
- await add(1, add(add(2, 3), 4))
90
+ await square(add(1, add(add(2, 3), 4)))
88
91
  )
89
92
 
90
93
  process.exit(0)
@@ -104,28 +107,28 @@ pkill sendscript
104
107
 
105
108
  ## Reference
106
109
 
107
- SendScript is essentially a way to serialize a program to then send over the wire
108
- and execute it somewhere else.
110
+ SendScript is essentially a way to serialize a program to then send over the
111
+ wire and execute it somewhere else.
109
112
 
110
113
  We only have two modules. One that helps you write programs that can be sent
111
114
  over the wire and another for running that program.
112
115
 
113
- ### `sendscript/dsl.mjs`
116
+ ### `sendscript/api.mjs`
114
117
 
115
- The dsl module exports a function that takes two arguments.
118
+ The api module exports a function that takes two arguments.
116
119
 
117
120
  1. The schema, which represents the values that are available.
118
121
  2. The function that will be called with the serializable version of the
119
122
  program.
120
123
 
121
124
  It returns an object that contains functions which are defined in the schema.
122
- These functions are a JavaScript DSL for writing programs that can be sent to
125
+ These functions are a JavaScript API for writing programs that can be sent to
123
126
  a server.
124
127
 
125
128
  ```js
126
- import dsl from './dsl.mjs'
129
+ import api from './api.mjs'
127
130
 
128
- const { add, subtract } = dsl(
131
+ const { add, subtract } = api(
129
132
  ['add', 'subtract'],
130
133
  serializableProgram => sendSomewhereToBeExecuted(serializableProgram)
131
134
  )
@@ -141,7 +144,7 @@ soon as await or `.then` is used.
141
144
  > Notice that you do not have to await the subtract call. You only need to
142
145
  > await when you want to execute the program.
143
146
 
144
- This DSL is composable and wrappable.
147
+ This API is composable and wrappable.
145
148
 
146
149
  ### `sendscript/exec.mjs`
147
150
 
@@ -158,8 +161,8 @@ exec({
158
161
 
159
162
  The array you see here is the LISP that SendScript uses to represent programs.
160
163
 
161
- You could use SendScript without knowing the details of how the LISP works. It is an
162
- implementation detail and might change over time.
164
+ You could use SendScript without knowing the details of how the LISP works. It
165
+ is an implementation detail and might change over time.
163
166
 
164
167
  ## Tests
165
168
 
package/api.mjs ADDED
@@ -0,0 +1,32 @@
1
+ import promiseOnly from './promise-only.mjs'
2
+
3
+ const symbol = Symbol('api')
4
+ const isNonAPI = v => v?.[symbol] !== symbol
5
+ const promiseOnlyNonAPI = promiseOnly(isNonAPI)
6
+
7
+ export default function api (schema, call) {
8
+ return schema.reduce((api, name) => {
9
+ const then = (program) => (resolve, reject) =>
10
+ Promise.resolve(call(program)).then(resolve, reject)
11
+
12
+ const fn = (...args) => ({
13
+ [symbol]: symbol,
14
+ toJSON () {
15
+ return [fn, ...args]
16
+ },
17
+ async then (resolve, reject) {
18
+ return then(await promiseOnlyNonAPI([
19
+ fn, ...args
20
+ ]))(resolve, reject)
21
+ }
22
+ })
23
+
24
+ fn.toJSON = () => ['ref', name]
25
+ fn.then = then(fn)
26
+ fn[symbol] = symbol
27
+
28
+ api[name] = fn
29
+
30
+ return api
31
+ }, {})
32
+ }
@@ -1,10 +1,10 @@
1
1
  import { test } from 'tap'
2
- import dsl from './dsl.mjs'
2
+ import api from './api.mjs'
3
3
 
4
4
  test('return a constant value', async t => {
5
5
  t.plan(1)
6
6
 
7
- const { constant } = dsl(['constant'], v => {
7
+ const { constant } = api(['constant'], v => {
8
8
  t.equal(JSON.stringify(v), '["ref","constant"]')
9
9
  })
10
10
 
@@ -14,7 +14,7 @@ test('return a constant value', async t => {
14
14
  test('use function calls as arguments', async t => {
15
15
  t.plan(4)
16
16
 
17
- const { add } = dsl(['add'], b => {
17
+ const { add } = api(['add'], b => {
18
18
  t.equal(JSON.stringify(awaited), JSON.stringify(b))
19
19
  return 'done'
20
20
  })
@@ -1,7 +1,7 @@
1
1
  // ./example/client.socket.io.mjs
2
2
 
3
3
  import socketClient from 'socket.io-client'
4
- import dsl from '../dsl.mjs'
4
+ import api from '../api.mjs'
5
5
 
6
6
  const port = process.env.PORT || 3000
7
7
  const client = socketClient(`http://localhost:${port}`)
@@ -16,10 +16,10 @@ const exec = program => {
16
16
  })
17
17
  }
18
18
 
19
- const { add } = dsl(['add'], exec)
19
+ const { add, square } = api(['add', 'square'], exec)
20
20
 
21
21
  console.log(
22
- await add(1, add(add(2, 3), 4))
22
+ await square(add(1, add(add(2, 3), 4)))
23
23
  )
24
24
 
25
25
  process.exit(0)
package/example/math.mjs CHANGED
@@ -1,3 +1,4 @@
1
1
  // ./example/math.mjs
2
2
 
3
3
  export const add = (a, b) => a + b
4
+ export const square = a => a * a
package/exec.test.mjs CHANGED
@@ -108,3 +108,18 @@ test('should reject with the error of the called function', async t => {
108
108
 
109
109
  t.end()
110
110
  })
111
+
112
+ test('should not exec expressions in an object', async t => {
113
+ const env = {
114
+ throws () {
115
+ throw new Error('Should not have been called.')
116
+ }
117
+ }
118
+
119
+ const result = await exec(env, { quoted: ['throws'] })
120
+
121
+ t.same(result, {
122
+ quoted: ['throws']
123
+ })
124
+ t.end()
125
+ })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sendscript",
3
- "version": "0.0.0",
3
+ "version": "0.0.1",
4
4
  "description": "Blur the line between server and client code.",
5
5
  "module": true,
6
6
  "main": "index.mjs",
@@ -0,0 +1,13 @@
1
+ import curry from './curry.mjs'
2
+
3
+ const promiseOnly = curry(function promiseOnly (when, array) {
4
+ return array.reduce(async (asyncAcc, item) => {
5
+ const acc = await asyncAcc
6
+
7
+ acc.push(when(item) ? await item : item)
8
+
9
+ return acc
10
+ }, [])
11
+ })
12
+
13
+ export default promiseOnly
package/dsl.mjs DELETED
@@ -1,40 +0,0 @@
1
- const symbol = Symbol('dsl')
2
-
3
- // Only await values that are not part of the dsl.
4
- const promiseAllNonDSL = async values => values.reduce(async (_acc, value) => {
5
- const acc = await _acc
6
-
7
- if (value[symbol] === symbol) {
8
- acc.push(value)
9
- } else {
10
- acc.push(await value)
11
- }
12
-
13
- return acc
14
- }, [])
15
-
16
- export default function dsl (schema, call) {
17
- return schema.reduce((api, name) => {
18
- const then = (program) => (resolve, reject) =>
19
- Promise.resolve(call(program)).then(resolve, reject)
20
-
21
- const fn = (...args) => {
22
- // Only await non dsl values
23
- const v = [fn, ...args]
24
-
25
- v[symbol] = symbol
26
- v.then = async (...thenArgs) => {
27
- return then(await promiseAllNonDSL(v))(...thenArgs)
28
- }
29
- return v
30
- }
31
-
32
- fn.toJSON = () => ['ref', name]
33
- fn.then = then(fn)
34
- fn[symbol] = symbol
35
-
36
- api[name] = fn
37
-
38
- return api
39
- }, {})
40
- }