@solidjs/web 2.0.0-beta.22 → 2.0.0-beta.24
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/dist/dev.cjs +25 -1
- package/dist/dev.js +25 -2
- package/dist/server.cjs +109 -45
- package/dist/server.js +109 -46
- package/dist/web.cjs +25 -1
- package/dist/web.js +25 -2
- package/frames/dist/client.cjs +1467 -0
- package/frames/dist/client.js +1455 -0
- package/frames/dist/server.cjs +1723 -0
- package/frames/dist/server.js +1712 -0
- package/frames/package.json +30 -0
- package/package.json +78 -5
- package/serialization/dist/serialization.cjs +83 -0
- package/serialization/dist/serialization.js +82 -1
- package/serialization/types/index.d.ts +12 -0
- package/serialization/types-cjs/index.d.cts +12 -0
- package/server-functions/dist/client.cjs +82 -55
- package/server-functions/dist/client.js +83 -56
- package/server-functions/dist/server.cjs +28 -7
- package/server-functions/dist/server.js +28 -7
- package/types/client.d.ts +8 -0
- package/types/core.d.ts +2 -1
- package/types/frames/client.d.ts +53 -0
- package/types/frames/frame-client.d.ts +222 -0
- package/types/frames/frame-sink.d.ts +145 -0
- package/types/frames/frame-transport.d.ts +106 -0
- package/types/frames/serializer.d.ts +151 -0
- package/types/frames/server.d.ts +21 -0
- package/types/serializer.d.ts +12 -0
- package/types/server-functions/client.d.ts +24 -0
- package/types/server-functions/server.d.ts +17 -0
- package/types/server-functions/shared.d.ts +17 -0
- package/types/server.d.ts +2 -0
- package/types-cjs/client.d.cts +8 -0
- package/types-cjs/core.d.cts +2 -1
- package/types-cjs/frames/client.d.cts +53 -0
- package/types-cjs/frames/frame-client.d.cts +222 -0
- package/types-cjs/frames/frame-sink.d.cts +145 -0
- package/types-cjs/frames/frame-transport.d.cts +106 -0
- package/types-cjs/frames/serializer.d.cts +151 -0
- package/types-cjs/frames/server.d.cts +21 -0
- package/types-cjs/serializer.d.cts +12 -0
- package/types-cjs/server-functions/client.d.cts +24 -0
- package/types-cjs/server-functions/server.d.cts +17 -0
- package/types-cjs/server-functions/shared.d.cts +17 -0
- package/types-cjs/server.d.cts +2 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@solidjs/web/frames",
|
|
3
|
+
"main": "./dist/server.cjs",
|
|
4
|
+
"module": "./dist/server.js",
|
|
5
|
+
"types": "../types/frames/server.d.ts",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"browser": {
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "../types/frames/client.d.ts",
|
|
13
|
+
"default": "./dist/client.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "../types-cjs/frames/client.d.cts",
|
|
17
|
+
"default": "./dist/client.cjs"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "../types/frames/server.d.ts",
|
|
22
|
+
"default": "./dist/server.js"
|
|
23
|
+
},
|
|
24
|
+
"require": {
|
|
25
|
+
"types": "../types-cjs/frames/server.d.cts",
|
|
26
|
+
"default": "./dist/server.cjs"
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solidjs/web",
|
|
3
3
|
"description": "Solid's web runtime: client rendering, hydration, SSR, and DOM-specific control flow (Portal, Dynamic).",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.24",
|
|
5
5
|
"author": "Ryan Carniato",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"homepage": "https://solidjs.com",
|
|
@@ -34,7 +34,9 @@
|
|
|
34
34
|
"serialization/types-cjs",
|
|
35
35
|
"serialization/package.json",
|
|
36
36
|
"server-functions/dist",
|
|
37
|
-
"server-functions/package.json"
|
|
37
|
+
"server-functions/package.json",
|
|
38
|
+
"frames/dist",
|
|
39
|
+
"frames/package.json"
|
|
38
40
|
],
|
|
39
41
|
"exports": {
|
|
40
42
|
".": {
|
|
@@ -217,6 +219,76 @@
|
|
|
217
219
|
"default": "./server-functions/dist/client.cjs"
|
|
218
220
|
}
|
|
219
221
|
},
|
|
222
|
+
"./frames": {
|
|
223
|
+
"worker": {
|
|
224
|
+
"import": {
|
|
225
|
+
"types": "./types/frames/server.d.ts",
|
|
226
|
+
"default": "./frames/dist/server.js"
|
|
227
|
+
},
|
|
228
|
+
"require": {
|
|
229
|
+
"types": "./types-cjs/frames/server.d.cts",
|
|
230
|
+
"default": "./frames/dist/server.cjs"
|
|
231
|
+
}
|
|
232
|
+
},
|
|
233
|
+
"browser": {
|
|
234
|
+
"import": {
|
|
235
|
+
"types": "./types/frames/client.d.ts",
|
|
236
|
+
"default": "./frames/dist/client.js"
|
|
237
|
+
},
|
|
238
|
+
"require": {
|
|
239
|
+
"types": "./types-cjs/frames/client.d.cts",
|
|
240
|
+
"default": "./frames/dist/client.cjs"
|
|
241
|
+
}
|
|
242
|
+
},
|
|
243
|
+
"deno": {
|
|
244
|
+
"import": {
|
|
245
|
+
"types": "./types/frames/server.d.ts",
|
|
246
|
+
"default": "./frames/dist/server.js"
|
|
247
|
+
},
|
|
248
|
+
"require": {
|
|
249
|
+
"types": "./types-cjs/frames/server.d.cts",
|
|
250
|
+
"default": "./frames/dist/server.cjs"
|
|
251
|
+
}
|
|
252
|
+
},
|
|
253
|
+
"node": {
|
|
254
|
+
"import": {
|
|
255
|
+
"types": "./types/frames/server.d.ts",
|
|
256
|
+
"default": "./frames/dist/server.js"
|
|
257
|
+
},
|
|
258
|
+
"require": {
|
|
259
|
+
"types": "./types-cjs/frames/server.d.cts",
|
|
260
|
+
"default": "./frames/dist/server.cjs"
|
|
261
|
+
}
|
|
262
|
+
},
|
|
263
|
+
"import": {
|
|
264
|
+
"types": "./types/frames/client.d.ts",
|
|
265
|
+
"default": "./frames/dist/client.js"
|
|
266
|
+
},
|
|
267
|
+
"require": {
|
|
268
|
+
"types": "./types-cjs/frames/client.d.cts",
|
|
269
|
+
"default": "./frames/dist/client.cjs"
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
"./frames/server": {
|
|
273
|
+
"import": {
|
|
274
|
+
"types": "./types/frames/server.d.ts",
|
|
275
|
+
"default": "./frames/dist/server.js"
|
|
276
|
+
},
|
|
277
|
+
"require": {
|
|
278
|
+
"types": "./types-cjs/frames/server.d.cts",
|
|
279
|
+
"default": "./frames/dist/server.cjs"
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
"./frames/client": {
|
|
283
|
+
"import": {
|
|
284
|
+
"types": "./types/frames/client.d.ts",
|
|
285
|
+
"default": "./frames/dist/client.js"
|
|
286
|
+
},
|
|
287
|
+
"require": {
|
|
288
|
+
"types": "./types-cjs/frames/client.d.cts",
|
|
289
|
+
"default": "./frames/dist/client.cjs"
|
|
290
|
+
}
|
|
291
|
+
},
|
|
220
292
|
"./types/*": "./types/*"
|
|
221
293
|
},
|
|
222
294
|
"dependencies": {
|
|
@@ -224,17 +296,17 @@
|
|
|
224
296
|
"seroval-plugins": "~1.5.4"
|
|
225
297
|
},
|
|
226
298
|
"peerDependencies": {
|
|
227
|
-
"solid-js": "^2.0.0-beta.
|
|
299
|
+
"solid-js": "^2.0.0-beta.24"
|
|
228
300
|
},
|
|
229
301
|
"devDependencies": {
|
|
230
|
-
"solid-js": "2.0.0-beta.
|
|
302
|
+
"solid-js": "2.0.0-beta.24"
|
|
231
303
|
},
|
|
232
304
|
"scripts": {
|
|
233
305
|
"build": "npm-run-all -nl build:clean types:copy-jsx build:js",
|
|
234
306
|
"build:clean": "rimraf dist/",
|
|
235
307
|
"build:js": "rollup -c",
|
|
236
308
|
"link": "symlink-dir . node_modules/@solidjs/web",
|
|
237
|
-
"types": "npm-run-all -nl types:clean types:copy-jsx types:web types:copy-web types:web-storage types:copy-serialization types:copy-server-functions types:cjs",
|
|
309
|
+
"types": "npm-run-all -nl types:clean types:copy-jsx types:web types:copy-web types:web-storage types:copy-serialization types:copy-server-functions types:copy-frames types:cjs",
|
|
238
310
|
"types:clean": "rimraf types/ types-cjs/ storage/types/ storage/types-cjs/ serialization/types/ serialization/types-cjs/",
|
|
239
311
|
"types:copy-jsx": "ncp ../../node_modules/@dom-expressions/runtime/src/jsx.d.ts ./src/jsx.d.ts && ncp ../../node_modules/@dom-expressions/runtime/src/jsx-properties.d.ts ./src/jsx-properties.d.ts && dom-expressions-jsx-types --input ./src/jsx.d.ts --element \"SolidElement | Node | ArrayElement\" --import 'import type { Element as SolidElement } from \"solid-js\";'",
|
|
240
312
|
"types:web": "tsc --project ./tsconfig.build.json",
|
|
@@ -242,6 +314,7 @@
|
|
|
242
314
|
"types:web-storage": "tsc --project ./storage/tsconfig.build.json",
|
|
243
315
|
"types:copy-serialization": "node -e \"fs.mkdirSync('./serialization/types', { recursive: true }); fs.copyFileSync('../../node_modules/@dom-expressions/runtime/src/serializer.d.ts', './serialization/types/index.d.ts');\"",
|
|
244
316
|
"types:copy-server-functions": "node -e \"fs.mkdirSync('./types/server-functions', { recursive: true }); for (const f of ['shared', 'client', 'server']) fs.copyFileSync('../../node_modules/@dom-expressions/runtime/src/server-functions/' + f + '.d.ts', './types/server-functions/' + f + '.d.ts');\"",
|
|
317
|
+
"types:copy-frames": "node -e \"fs.mkdirSync('./types/frames', { recursive: true }); for (const f of ['frame-client', 'frame-transport', 'frame-sink', 'serializer']) fs.copyFileSync('../../node_modules/@dom-expressions/runtime/src/' + f + '.d.ts', './types/frames/' + f + '.d.ts'); for (const f of ['client', 'server']) fs.copyFileSync('./frames/types/' + f + '.d.ts', './types/frames/' + f + '.d.ts');\"",
|
|
245
318
|
"types:cjs": "node ../../scripts/sync-dual-types.mjs ./types ./types-cjs ./storage/types ./storage/types-cjs ./serialization/types ./serialization/types-cjs",
|
|
246
319
|
"test": "vitest run && vitest run --config vite.config.server.mjs && vitest run --config vite.config.hydrate.mjs",
|
|
247
320
|
"test:server": "vitest run --config vite.config.server.mjs",
|
|
@@ -73,10 +73,93 @@ function createJSONDeserializer(options) {
|
|
|
73
73
|
});
|
|
74
74
|
};
|
|
75
75
|
}
|
|
76
|
+
function createJSONSerializer({
|
|
77
|
+
onData,
|
|
78
|
+
onDone,
|
|
79
|
+
onError,
|
|
80
|
+
plugins,
|
|
81
|
+
disabledFeatures,
|
|
82
|
+
depthLimit
|
|
83
|
+
}) {
|
|
84
|
+
const resolved = resolveCodecOptions({
|
|
85
|
+
plugins,
|
|
86
|
+
disabledFeatures,
|
|
87
|
+
depthLimit
|
|
88
|
+
});
|
|
89
|
+
const refs = new Map();
|
|
90
|
+
const cancels = new Set();
|
|
91
|
+
let pendingWrites = 0;
|
|
92
|
+
let flushed = false;
|
|
93
|
+
let done = false;
|
|
94
|
+
const maybeDone = () => {
|
|
95
|
+
if (flushed && pendingWrites === 0 && !done) {
|
|
96
|
+
done = true;
|
|
97
|
+
onDone && onDone();
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
return {
|
|
101
|
+
write(key, value) {
|
|
102
|
+
if (flushed) return;
|
|
103
|
+
pendingWrites++;
|
|
104
|
+
let settled = false;
|
|
105
|
+
let cancel = null;
|
|
106
|
+
const stream = seroval.toCrossJSONStream(value, {
|
|
107
|
+
refs,
|
|
108
|
+
plugins: resolved.plugins,
|
|
109
|
+
disabledFeatures: resolved.disabledFeatures,
|
|
110
|
+
onParse(node, initial) {
|
|
111
|
+
onData({
|
|
112
|
+
key,
|
|
113
|
+
node,
|
|
114
|
+
initial
|
|
115
|
+
});
|
|
116
|
+
},
|
|
117
|
+
onError,
|
|
118
|
+
onDone() {
|
|
119
|
+
settled = true;
|
|
120
|
+
if (cancel) cancels.delete(cancel);
|
|
121
|
+
pendingWrites--;
|
|
122
|
+
maybeDone();
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
if (!settled) {
|
|
126
|
+
cancel = stream;
|
|
127
|
+
cancels.add(cancel);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
flush() {
|
|
131
|
+
flushed = true;
|
|
132
|
+
maybeDone();
|
|
133
|
+
},
|
|
134
|
+
close() {
|
|
135
|
+
flushed = true;
|
|
136
|
+
for (const cancel of cancels) cancel();
|
|
137
|
+
cancels.clear();
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
function createJSONDataTable(options) {
|
|
142
|
+
const deserialize = createJSONDeserializer(options);
|
|
143
|
+
const table = new Map();
|
|
144
|
+
return {
|
|
145
|
+
apply(record) {
|
|
146
|
+
const value = deserialize(record.node);
|
|
147
|
+
if (record.initial) table.set(record.key, value);
|
|
148
|
+
},
|
|
149
|
+
get(key) {
|
|
150
|
+
return table.get(key);
|
|
151
|
+
},
|
|
152
|
+
resolve(ref) {
|
|
153
|
+
return table.get(ref.$ref);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
}
|
|
76
157
|
|
|
77
158
|
exports.DEFAULT_WEB_PLUGINS = DEFAULT_WEB_PLUGINS;
|
|
78
159
|
exports.createHydrationSerializer = createHydrationSerializer;
|
|
160
|
+
exports.createJSONDataTable = createJSONDataTable;
|
|
79
161
|
exports.createJSONDeserializer = createJSONDeserializer;
|
|
162
|
+
exports.createJSONSerializer = createJSONSerializer;
|
|
80
163
|
exports.createSerializer = createSerializer;
|
|
81
164
|
exports.getLocalHeaderScript = getLocalHeaderScript;
|
|
82
165
|
exports.resolveSerializerPlugins = resolveSerializerPlugins;
|
|
@@ -71,5 +71,86 @@ function createJSONDeserializer(options) {
|
|
|
71
71
|
});
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
+
function createJSONSerializer({
|
|
75
|
+
onData,
|
|
76
|
+
onDone,
|
|
77
|
+
onError,
|
|
78
|
+
plugins,
|
|
79
|
+
disabledFeatures,
|
|
80
|
+
depthLimit
|
|
81
|
+
}) {
|
|
82
|
+
const resolved = resolveCodecOptions({
|
|
83
|
+
plugins,
|
|
84
|
+
disabledFeatures,
|
|
85
|
+
depthLimit
|
|
86
|
+
});
|
|
87
|
+
const refs = new Map();
|
|
88
|
+
const cancels = new Set();
|
|
89
|
+
let pendingWrites = 0;
|
|
90
|
+
let flushed = false;
|
|
91
|
+
let done = false;
|
|
92
|
+
const maybeDone = () => {
|
|
93
|
+
if (flushed && pendingWrites === 0 && !done) {
|
|
94
|
+
done = true;
|
|
95
|
+
onDone && onDone();
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
return {
|
|
99
|
+
write(key, value) {
|
|
100
|
+
if (flushed) return;
|
|
101
|
+
pendingWrites++;
|
|
102
|
+
let settled = false;
|
|
103
|
+
let cancel = null;
|
|
104
|
+
const stream = toCrossJSONStream(value, {
|
|
105
|
+
refs,
|
|
106
|
+
plugins: resolved.plugins,
|
|
107
|
+
disabledFeatures: resolved.disabledFeatures,
|
|
108
|
+
onParse(node, initial) {
|
|
109
|
+
onData({
|
|
110
|
+
key,
|
|
111
|
+
node,
|
|
112
|
+
initial
|
|
113
|
+
});
|
|
114
|
+
},
|
|
115
|
+
onError,
|
|
116
|
+
onDone() {
|
|
117
|
+
settled = true;
|
|
118
|
+
if (cancel) cancels.delete(cancel);
|
|
119
|
+
pendingWrites--;
|
|
120
|
+
maybeDone();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
if (!settled) {
|
|
124
|
+
cancel = stream;
|
|
125
|
+
cancels.add(cancel);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
flush() {
|
|
129
|
+
flushed = true;
|
|
130
|
+
maybeDone();
|
|
131
|
+
},
|
|
132
|
+
close() {
|
|
133
|
+
flushed = true;
|
|
134
|
+
for (const cancel of cancels) cancel();
|
|
135
|
+
cancels.clear();
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function createJSONDataTable(options) {
|
|
140
|
+
const deserialize = createJSONDeserializer(options);
|
|
141
|
+
const table = new Map();
|
|
142
|
+
return {
|
|
143
|
+
apply(record) {
|
|
144
|
+
const value = deserialize(record.node);
|
|
145
|
+
if (record.initial) table.set(record.key, value);
|
|
146
|
+
},
|
|
147
|
+
get(key) {
|
|
148
|
+
return table.get(key);
|
|
149
|
+
},
|
|
150
|
+
resolve(ref) {
|
|
151
|
+
return table.get(ref.$ref);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
74
155
|
|
|
75
|
-
export { DEFAULT_WEB_PLUGINS, createHydrationSerializer, createJSONDeserializer, createSerializer, getLocalHeaderScript, resolveSerializerPlugins, serializeJSON };
|
|
156
|
+
export { DEFAULT_WEB_PLUGINS, createHydrationSerializer, createJSONDataTable, createJSONDeserializer, createJSONSerializer, createSerializer, getLocalHeaderScript, resolveSerializerPlugins, serializeJSON };
|
|
@@ -137,3 +137,15 @@ export function serializeJSON(value: unknown, options: JSONSerializeOptions): ()
|
|
|
137
137
|
* settles the async values referenced inside it.
|
|
138
138
|
*/
|
|
139
139
|
export function createJSONDeserializer(options?: JSONCodecOptions): <T>(node: SerovalNode) => T;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A resident, response-scoped decode table over the keyed JSON codec: apply
|
|
143
|
+
* each frame `data` chunk with `apply`, resolve `{ $ref }` slot args with
|
|
144
|
+
* `resolve`. The frames client host wires one per response
|
|
145
|
+
* (`applyData: c => table.apply(c)`).
|
|
146
|
+
*/
|
|
147
|
+
export interface JSONDataTable {
|
|
148
|
+
apply(chunk: { key?: string; node?: unknown; initial?: boolean }): void;
|
|
149
|
+
resolve<T = unknown>(ref: { $ref: string }): T;
|
|
150
|
+
}
|
|
151
|
+
export function createJSONDataTable(options?: JSONCodecOptions): JSONDataTable;
|
|
@@ -137,3 +137,15 @@ export function serializeJSON(value: unknown, options: JSONSerializeOptions): ()
|
|
|
137
137
|
* settles the async values referenced inside it.
|
|
138
138
|
*/
|
|
139
139
|
export function createJSONDeserializer(options?: JSONCodecOptions): <T>(node: SerovalNode) => T;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* A resident, response-scoped decode table over the keyed JSON codec: apply
|
|
143
|
+
* each frame `data` chunk with `apply`, resolve `{ $ref }` slot args with
|
|
144
|
+
* `resolve`. The frames client host wires one per response
|
|
145
|
+
* (`applyData: c => table.apply(c)`).
|
|
146
|
+
*/
|
|
147
|
+
export interface JSONDataTable {
|
|
148
|
+
apply(chunk: { key?: string; node?: unknown; initial?: boolean }): void;
|
|
149
|
+
resolve<T = unknown>(ref: { $ref: string }): T;
|
|
150
|
+
}
|
|
151
|
+
export function createJSONDataTable(options?: JSONCodecOptions): JSONDataTable;
|
|
@@ -23,19 +23,6 @@ function resolveCodecOptions({
|
|
|
23
23
|
depthLimit: depthLimit === undefined ? JSON_CODEC_DEPTH_LIMIT : depthLimit
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
|
-
function serializeJSON(value, {
|
|
27
|
-
onParse,
|
|
28
|
-
onDone,
|
|
29
|
-
onError,
|
|
30
|
-
...codecOptions
|
|
31
|
-
}) {
|
|
32
|
-
return seroval.toCrossJSONStream(value, {
|
|
33
|
-
onParse,
|
|
34
|
-
onDone,
|
|
35
|
-
onError,
|
|
36
|
-
...resolveCodecOptions(codecOptions)
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
26
|
function createJSONDeserializer(options) {
|
|
40
27
|
const refs = new Map();
|
|
41
28
|
const resolved = resolveCodecOptions(options);
|
|
@@ -53,9 +40,6 @@ const codecConfig = {
|
|
|
53
40
|
function configureServerFunctionsCodec(codec) {
|
|
54
41
|
codecConfig.codec = codec;
|
|
55
42
|
}
|
|
56
|
-
function getServerFunctionsCodec() {
|
|
57
|
-
return codecConfig.codec;
|
|
58
|
-
}
|
|
59
43
|
const flightConfig = {
|
|
60
44
|
consumer: undefined
|
|
61
45
|
};
|
|
@@ -122,7 +106,8 @@ const BodyFormat = {
|
|
|
122
106
|
Blob: "4",
|
|
123
107
|
File: "5",
|
|
124
108
|
ArrayBuffer: "6",
|
|
125
|
-
Uint8Array: "7"
|
|
109
|
+
Uint8Array: "7",
|
|
110
|
+
Json: "8"
|
|
126
111
|
};
|
|
127
112
|
function getHeadersAndBody(body) {
|
|
128
113
|
switch (true) {
|
|
@@ -192,6 +177,8 @@ async function extractBody(source, codecOptions) {
|
|
|
192
177
|
switch (true) {
|
|
193
178
|
case format === BodyFormat.Serialized:
|
|
194
179
|
return await deserializeStream(clone, codecOptions);
|
|
180
|
+
case format === BodyFormat.Json:
|
|
181
|
+
return JSON.parse(await clone.text());
|
|
195
182
|
case format === BodyFormat.String:
|
|
196
183
|
return await clone.text();
|
|
197
184
|
case format === BodyFormat.File:
|
|
@@ -214,17 +201,6 @@ async function extractBody(source, codecOptions) {
|
|
|
214
201
|
}
|
|
215
202
|
return undefined;
|
|
216
203
|
}
|
|
217
|
-
function createChunk(data) {
|
|
218
|
-
const encodeData = new TextEncoder().encode(data);
|
|
219
|
-
const bytes = encodeData.length;
|
|
220
|
-
const baseHex = bytes.toString(16);
|
|
221
|
-
const totalHex = "00000000".substring(0, 8 - baseHex.length) + baseHex;
|
|
222
|
-
const head = new TextEncoder().encode(`;0x${totalHex};`);
|
|
223
|
-
const chunk = new Uint8Array(12 + bytes);
|
|
224
|
-
chunk.set(head);
|
|
225
|
-
chunk.set(encodeData, 12);
|
|
226
|
-
return chunk;
|
|
227
|
-
}
|
|
228
204
|
class ChunkReader {
|
|
229
205
|
constructor(stream) {
|
|
230
206
|
this.reader = stream.getReader();
|
|
@@ -281,28 +257,6 @@ class ChunkReader {
|
|
|
281
257
|
}
|
|
282
258
|
}
|
|
283
259
|
}
|
|
284
|
-
function serializeStream(value, codecOptions) {
|
|
285
|
-
return new ReadableStream({
|
|
286
|
-
start(controller) {
|
|
287
|
-
serializeJSON(value, {
|
|
288
|
-
...codecOptions,
|
|
289
|
-
onParse(node) {
|
|
290
|
-
controller.enqueue(createChunk(JSON.stringify(node)));
|
|
291
|
-
},
|
|
292
|
-
onDone() {
|
|
293
|
-
controller.close();
|
|
294
|
-
},
|
|
295
|
-
onError(error) {
|
|
296
|
-
controller.error(error);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
async function serializeString(value, codecOptions) {
|
|
303
|
-
const response = new Response(serializeStream(value, codecOptions));
|
|
304
|
-
return await response.text();
|
|
305
|
-
}
|
|
306
260
|
async function deserializeStream(source, codecOptions) {
|
|
307
261
|
if (!source.body) {
|
|
308
262
|
throw new Error("missing body");
|
|
@@ -326,16 +280,43 @@ async function decodeResponse(response, codecOptions) {
|
|
|
326
280
|
|
|
327
281
|
const config = {
|
|
328
282
|
endpoint: "/_server",
|
|
329
|
-
prepareRequest: undefined
|
|
283
|
+
prepareRequest: undefined,
|
|
284
|
+
responseHandler: undefined,
|
|
285
|
+
serializeArgs: undefined
|
|
330
286
|
};
|
|
287
|
+
function isJSONSafe(value) {
|
|
288
|
+
if (value === null) return true;
|
|
289
|
+
const t = typeof value;
|
|
290
|
+
if (t === "string" || t === "boolean") return true;
|
|
291
|
+
if (t === "number") return Number.isFinite(value);
|
|
292
|
+
if (t !== "object") return false;
|
|
293
|
+
if (Array.isArray(value)) {
|
|
294
|
+
for (const v of value) if (!isJSONSafe(v)) return false;
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
297
|
+
const proto = Object.getPrototypeOf(value);
|
|
298
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
299
|
+
for (const k in value) if (!isJSONSafe(value[k])) return false;
|
|
300
|
+
return true;
|
|
301
|
+
}
|
|
302
|
+
function serializeArguments(args) {
|
|
303
|
+
if (!config.serializeArgs) {
|
|
304
|
+
throw new Error("Server function arguments are sent as JSON by default and these " + "arguments are not JSON-serializable. Call enableRichArguments() " + "(from the server-functions rich-args entry) once at startup to " + "send Dates, Maps, Sets, typed arrays, etc. through the codec — or " + "pass a single Blob/FormData/File argument, which has a native " + "HTTP encoding.");
|
|
305
|
+
}
|
|
306
|
+
return config.serializeArgs(args);
|
|
307
|
+
}
|
|
331
308
|
function configureServerFunctionsClient({
|
|
332
309
|
endpoint,
|
|
333
310
|
codec,
|
|
334
|
-
prepareRequest
|
|
311
|
+
prepareRequest,
|
|
312
|
+
responseHandler,
|
|
313
|
+
serializeArgs
|
|
335
314
|
} = {}) {
|
|
336
315
|
if (endpoint !== undefined) config.endpoint = endpoint;
|
|
337
316
|
if (codec !== undefined) configureServerFunctionsCodec(codec);
|
|
338
317
|
if (prepareRequest !== undefined) config.prepareRequest = prepareRequest;
|
|
318
|
+
if (responseHandler !== undefined) config.responseHandler = responseHandler;
|
|
319
|
+
if (serializeArgs !== undefined) config.serializeArgs = serializeArgs;
|
|
339
320
|
}
|
|
340
321
|
let INSTANCE = 0;
|
|
341
322
|
async function createRequest(base, id, instance, options, meta) {
|
|
@@ -377,9 +358,20 @@ async function initializeResponse(base, id, instance, options, args, meta) {
|
|
|
377
358
|
}, meta);
|
|
378
359
|
}
|
|
379
360
|
}
|
|
361
|
+
if (isJSONSafe(args)) {
|
|
362
|
+
return createRequest(base, id, instance, {
|
|
363
|
+
...options,
|
|
364
|
+
body: JSON.stringify(args),
|
|
365
|
+
headers: {
|
|
366
|
+
...options.headers,
|
|
367
|
+
"Content-Type": "application/json",
|
|
368
|
+
[BODY_FORMAT_HEADER]: BodyFormat.Json
|
|
369
|
+
}
|
|
370
|
+
}, meta);
|
|
371
|
+
}
|
|
380
372
|
return createRequest(base, id, instance, {
|
|
381
373
|
...options,
|
|
382
|
-
body: await
|
|
374
|
+
body: await serializeArguments(args),
|
|
383
375
|
headers: {
|
|
384
376
|
...options.headers,
|
|
385
377
|
"Content-Type": "text/plain",
|
|
@@ -389,7 +381,21 @@ async function initializeResponse(base, id, instance, options, args, meta) {
|
|
|
389
381
|
}
|
|
390
382
|
async function fetchServerFunction(base, id, options, args, meta) {
|
|
391
383
|
const instance = `server-function:${INSTANCE++}`;
|
|
384
|
+
const handler = config.responseHandler;
|
|
385
|
+
const context = handler && handler.capture ? handler.capture({
|
|
386
|
+
id,
|
|
387
|
+
meta
|
|
388
|
+
}) : undefined;
|
|
392
389
|
const response = await initializeResponse(base, id, instance, options, args, meta);
|
|
390
|
+
if (handler) {
|
|
391
|
+
const handled = handler.handle(response, {
|
|
392
|
+
id,
|
|
393
|
+
meta,
|
|
394
|
+
args,
|
|
395
|
+
context
|
|
396
|
+
});
|
|
397
|
+
if (handled !== undefined) return handled;
|
|
398
|
+
}
|
|
393
399
|
if (response.headers.has(SINGLE_FLIGHT_HEADER)) {
|
|
394
400
|
const consumer = getFlightDataConsumer();
|
|
395
401
|
if (consumer) {
|
|
@@ -416,7 +422,18 @@ function createServerReference(id, name, base) {
|
|
|
416
422
|
const metadata = name === undefined ? {} : {
|
|
417
423
|
name
|
|
418
424
|
};
|
|
419
|
-
const fn = (...args) =>
|
|
425
|
+
const fn = (...args) => {
|
|
426
|
+
const handler = config.responseHandler;
|
|
427
|
+
if (handler && handler.intercept) {
|
|
428
|
+
const hit = handler.intercept({
|
|
429
|
+
id,
|
|
430
|
+
meta: metadata,
|
|
431
|
+
args
|
|
432
|
+
});
|
|
433
|
+
if (hit !== undefined) return hit;
|
|
434
|
+
}
|
|
435
|
+
return fetchServerFunction(base || config.endpoint, id, {}, args, metadata);
|
|
436
|
+
};
|
|
420
437
|
fn[SERVER_FUNCTION_METADATA] = metadata;
|
|
421
438
|
return new Proxy(fn, {
|
|
422
439
|
get(target, prop) {
|
|
@@ -437,9 +454,19 @@ function GET(fn) {
|
|
|
437
454
|
...getServerFunctionMetadata(fn)
|
|
438
455
|
};
|
|
439
456
|
const wrapped = async (...args) => {
|
|
457
|
+
const handler = config.responseHandler;
|
|
458
|
+
if (handler && handler.intercept) {
|
|
459
|
+
const hit = handler.intercept({
|
|
460
|
+
id,
|
|
461
|
+
meta: metadata,
|
|
462
|
+
args
|
|
463
|
+
});
|
|
464
|
+
if (hit !== undefined) return hit;
|
|
465
|
+
}
|
|
440
466
|
let base = `${config.endpoint}?id=${encodeURIComponent(id)}`;
|
|
441
467
|
if (args.length) {
|
|
442
|
-
|
|
468
|
+
const encoded = isJSONSafe(args) ? JSON.stringify(args) : await serializeArguments(args);
|
|
469
|
+
base += `&args=${encodeURIComponent(encoded)}`;
|
|
443
470
|
}
|
|
444
471
|
return fetchServerFunction(base, id, {
|
|
445
472
|
method: "GET"
|