@@ -53,10 +53,11 @@ using more advanced (de)serialization libraries.
5353SendScript produces an intermediate JSON representation of the program. Let's see what that looks like.
5454
5555``` js
56- import stringify from ' sendscript/stringify.mjs'
57- import module from ' sendscript/module .mjs'
56+ import Stringify from ' sendscript/stringify.mjs'
57+ import references from ' sendscript/references .mjs'
5858
59- const { add } = module ([' add' ])
59+ const { add } = references ([' add' ])
60+ const stringify = Stringify ()
6061
6162console .log (stringify (add (1 ,2 )))
6263```
@@ -75,7 +76,7 @@ const module = {
7576 }
7677}
7778
78- const parse = Parse (module )
79+ const parse = Parse ([ ' add ' ], module )
7980
8081const program = ' ["call",["ref","add"],[1,2]]'
8182
@@ -131,7 +132,8 @@ import { Server } from 'socket.io'
131132import Parse from ' sendscript/parse.mjs'
132133import * as math from ' ./math.mjs'
133134
134- const parse = Parse (math)
135+ const schema = Object .keys (math)
136+ const parse = Parse (schema, math)
135137const server = new Server ()
136138const port = process .env .PORT || 3000
137139
@@ -158,11 +160,13 @@ Now for a client that sends a program to the server.
158160// ./example/client.socket.io.mjs
159161
160162import socketClient from ' socket.io-client'
161- import stringify from ' sendscript/stringify.mjs'
162- import module from ' sendscript/module.mjs'
163- import * as math from ' ./math.mjs'
163+ import Stringify from ' sendscript/stringify.mjs'
164+ import references from ' sendscript/references.mjs'
164165import assert from ' node:assert'
165166
167+ const { add , square } = references ([' add' , ' square' ])
168+ const stringify = Stringify ()
169+
166170const port = process .env .PORT || 3000
167171const client = socketClient (` http://localhost:${ port} ` )
168172
@@ -176,8 +180,6 @@ const send = program => {
176180 })
177181}
178182
179- const { add , square } = module (math)
180-
181183// The program to be sent over the wire
182184const program = square (add (1 , add (add (2 , 3 ), 4 )))
183185
@@ -253,52 +255,31 @@ export const add = (a: number, b: number) => a + b
253255export const square = (a : number ) => a * a
254256```
255257
256- We want to use this module on the client. We create a client version of that module and coerce the types to match those of the server.
257-
258- ``` bash
259- cat ./example/typescript/math.client.ts
260- ```
261- ``` ts
262- import module from ' sendscript/module.mjs'
263- import type * as mathTypes from ' ./math.ts'
264-
265- const math = module ([
266- ' add' ,
267- ' square'
268- ]) as typeof mathTypes
269-
270- export default math
271- ```
272-
273- We now use the client version of this module.
258+ We can then coerce the types of the instrumented stubs.
274259
275260``` bash
276261cat ./example/typescript/client.ts
277262```
278263``` ts
279- import stringify from ' sendscript/stringify.mjs'
264+ import math from ' ./math.client.ts'
265+ import Stringify from ' sendscript/stringify.mjs'
266+
267+ const stringify = Stringify ()
280268
281- async function send<T >(program : T ): Promise <T >{
269+ // The return type of this function matches the type passed as the return of the program.
270+ async function send<T >(program : T ): Promise <T > {
282271 return (await fetch (' /api' , {
283272 method: ' POST' ,
284273 body: stringify (program )
285274 })).json ()
286275}
287276
288- import math from ' ./math.client.ts'
289-
290- const { add, square } = math
291-
292277send (square (add (1 , 2 )))
293278```
294279
295280We'll also generate the docs for this module.
296281
297282``` bash
298- npm install --no-save \
299- typedoc \
300- typedoc-plugin-markdown
301-
302283npx typedoc --plugin typedoc-plugin-markdown --out ./example/typescript/docs ./example/typescript/math.ts
303284```
304285
@@ -316,32 +297,33 @@ Sendscript allows you to define your API as a **nested object of functions**, ma
316297
317298### Defining a Nested Module
318299
319- You can define a schema as either:
320-
321- 1 . ** An object with nested objects** – submodules.
322- 2 . ** An array of function names** – automatically instrumented.
300+ You can define a schema as ** an array of function names**
323301
324302``` js
325- import module from ' sendscript/module.mjs'
326-
327- const myModule = module ({
328- math: [' add' , ' sub' ],
329-
330- // Use an object with keys and true value
331- vector: {
332- add: true ,
333- multiply: true
334- },
335303
336- // or use an array.
337- utils: [' identity' , ' always' ],
304+ const schema = [
305+ ' help' ,
306+ ' version' ,
307+
308+ [' math' , [
309+ ' add' ,
310+ ' sub'
311+ ]],
312+ [' vector' , [
313+ ' add' ,
314+ ' multiply'
315+ ]],
316+ [' utils' , [
317+ ' identity' ,
318+ ' always'
319+ ]],
338320})
339321```
340322
341323Functions are referenced via their ** path in the module tree** :
342324
343325``` js
344- const { math , vector } = myModule
326+ const { math , vector } = references (schema)
345327
346328math .add (
347329 1 ,
@@ -389,9 +371,9 @@ Here's how to use [superjson](https://github.com/blitz-js/superjson) to support
389371
390372``` js
391373import SuperJSON from ' superjson'
392- import stringify from ' sendscript/stringify.mjs'
374+ import Stringify from ' sendscript/stringify.mjs'
375+ import references from ' sendscript/references.mjs'
393376import Parse from ' sendscript/parse.mjs'
394- import module from ' sendscript/module.mjs'
395377
396378const leafSerializer = (value ) => {
397379 if (value === undefined ) return JSON .stringify ({ __undefined__: true })
@@ -404,7 +386,10 @@ const leafDeserializer = (text) => {
404386 return SuperJSON .deserialize (parsed)
405387}
406388
407- const { processData } = module ([' processData' ])
389+ const schema = [' processData' ]
390+
391+ const { processData } = references (schema)
392+ const stringify = Stringify (leafSerializer)
408393
409394// Program with Date, RegExp, and other types
410395const program = {
@@ -416,17 +401,20 @@ const program = {
416401}
417402
418403// Serialize with custom leaf serializer
419- const json = stringify (processData (program), leafSerializer )
404+ const json = stringify (processData (program))
420405
421- // Parse with custom leaf deserializer
422- const parse = Parse ( {
406+ // The environment
407+ const env = {
423408 processData : (data ) => ({
424409 success: true ,
425410 received: data
426411 })
427- })
412+ }
413+
414+ // Parse with custom leaf deserializer
415+ const parse = Parse (schema, env, leadDeserializer)
428416
429- const result = parse (json, leafDeserializer )
417+ const result = parse (json)
430418```
431419
432420The leaf wrapper format is ` ['leaf', serializedPayload] ` , making it unambiguous and safe from colliding with SendScript operators.
@@ -441,19 +429,19 @@ npm t -- report text-summary
441429```
442430```
443431
444- > sendscript@1.1 .0 test
432+ > sendscript@2.0 .0 test
445433> tap -R silent
446434
447435
448- > sendscript@1.1 .0 test
436+ > sendscript@2.0 .0 test
449437> tap report text-summary
450438
451439
452440=============================== Coverage summary ===============================
453- Statements : 100% ( 328/328 )
454- Branches : 100% ( 138/138 )
455- Functions : 100% ( 23/23 )
456- Lines : 100% ( 328/328 )
441+ Statements : 100% ( 348/348 )
442+ Branches : 100% ( 145/145 )
443+ Functions : 100% ( 24/24 )
444+ Lines : 100% ( 348/348 )
457445================================================================================
458446```
459447
0 commit comments