spiceflow 0.0.7 → 1.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/README.md +1 -171
- package/dist/client/errors.d.ts +7 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +18 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/index.d.ts +15 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +376 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/types.d.ts +87 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/utils.d.ts +2 -0
- package/dist/client/utils.d.ts.map +1 -0
- package/dist/client/utils.js +9 -0
- package/dist/client/utils.js.map +1 -0
- package/dist/client/ws.d.ts +15 -0
- package/dist/client/ws.d.ts.map +1 -0
- package/dist/client/ws.js +51 -0
- package/dist/client/ws.js.map +1 -0
- package/dist/client.test.d.ts +2 -0
- package/dist/client.test.d.ts.map +1 -0
- package/dist/client.test.js +237 -0
- package/dist/client.test.js.map +1 -0
- package/dist/elysia-fork/context.d.ts +87 -0
- package/dist/elysia-fork/context.d.ts.map +1 -0
- package/dist/elysia-fork/context.js +2 -0
- package/dist/elysia-fork/context.js.map +1 -0
- package/dist/elysia-fork/error.d.ts +246 -0
- package/dist/elysia-fork/error.d.ts.map +1 -0
- package/dist/elysia-fork/error.js +195 -0
- package/dist/elysia-fork/error.js.map +1 -0
- package/dist/elysia-fork/types.d.ts +570 -0
- package/dist/elysia-fork/types.d.ts.map +1 -0
- package/dist/elysia-fork/types.js +3 -0
- package/dist/elysia-fork/types.js.map +1 -0
- package/dist/elysia-fork/utils.d.ts +134 -0
- package/dist/elysia-fork/utils.d.ts.map +1 -0
- package/dist/elysia-fork/utils.js +70 -0
- package/dist/elysia-fork/utils.js.map +1 -0
- package/dist/index.d.ts +2 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -22
- package/dist/index.js.map +1 -1
- package/dist/spiceflow.d.ts +237 -0
- package/dist/spiceflow.d.ts.map +1 -0
- package/dist/spiceflow.js +484 -0
- package/dist/spiceflow.js.map +1 -0
- package/dist/spiceflow.test.d.ts +2 -0
- package/dist/spiceflow.test.d.ts.map +1 -0
- package/dist/spiceflow.test.js +225 -0
- package/dist/spiceflow.test.js.map +1 -0
- package/dist/stream.test.d.ts +2 -0
- package/dist/stream.test.d.ts.map +1 -0
- package/dist/stream.test.js +286 -0
- package/dist/stream.test.js.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +4 -20
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +17 -46
- package/dist/utils.js.map +1 -1
- package/package.json +12 -37
- package/src/client/errors.ts +21 -0
- package/src/client/index.ts +541 -0
- package/src/client/types.ts +233 -0
- package/src/client/utils.ts +7 -0
- package/src/client/ws.ts +99 -0
- package/src/client.test.ts +235 -0
- package/src/elysia-fork/context.ts +196 -0
- package/src/elysia-fork/error.ts +293 -0
- package/src/elysia-fork/types.ts +1353 -0
- package/src/elysia-fork/utils.ts +85 -0
- package/src/index.ts +2 -34
- package/src/spiceflow.test.ts +290 -0
- package/src/spiceflow.ts +1251 -0
- package/src/stream.test.ts +342 -0
- package/src/types.ts +0 -0
- package/src/utils.ts +21 -70
- package/context.d.ts +0 -2
- package/context.js +0 -1
- package/dist/babel.test.d.ts +0 -2
- package/dist/babel.test.d.ts.map +0 -1
- package/dist/babel.test.js +0 -27
- package/dist/babel.test.js.map +0 -1
- package/dist/babelDebugOutputs.d.ts +0 -9
- package/dist/babelDebugOutputs.d.ts.map +0 -1
- package/dist/babelDebugOutputs.js +0 -34
- package/dist/babelDebugOutputs.js.map +0 -1
- package/dist/babelTransformRpc.d.ts +0 -19
- package/dist/babelTransformRpc.d.ts.map +0 -1
- package/dist/babelTransformRpc.js +0 -285
- package/dist/babelTransformRpc.js.map +0 -1
- package/dist/browser.d.ts +0 -8
- package/dist/browser.d.ts.map +0 -1
- package/dist/browser.js +0 -126
- package/dist/browser.js.map +0 -1
- package/dist/build.d.ts +0 -13
- package/dist/build.d.ts.map +0 -1
- package/dist/build.js +0 -230
- package/dist/build.js.map +0 -1
- package/dist/cli.d.ts +0 -3
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js +0 -111
- package/dist/cli.js.map +0 -1
- package/dist/context-internal.d.ts +0 -20
- package/dist/context-internal.d.ts.map +0 -1
- package/dist/context-internal.js +0 -16
- package/dist/context-internal.js.map +0 -1
- package/dist/context.d.ts +0 -2
- package/dist/context.d.ts.map +0 -1
- package/dist/context.js +0 -2
- package/dist/context.js.map +0 -1
- package/dist/expose.d.ts +0 -6
- package/dist/expose.d.ts.map +0 -1
- package/dist/expose.js +0 -32
- package/dist/expose.js.map +0 -1
- package/dist/headers.d.ts +0 -2
- package/dist/headers.d.ts.map +0 -1
- package/dist/headers.js +0 -18
- package/dist/headers.js.map +0 -1
- package/dist/jsonRpc.d.ts +0 -32
- package/dist/jsonRpc.d.ts.map +0 -1
- package/dist/jsonRpc.js +0 -3
- package/dist/jsonRpc.js.map +0 -1
- package/dist/server.d.ts +0 -32
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js +0 -292
- package/dist/server.js.map +0 -1
- package/headers.d.ts +0 -2
- package/headers.js +0 -1
- package/sdk-template/package.json +0 -22
- package/sdk-template/src/index.ts +0 -2
- package/sdk-template/src/v1/example.ts +0 -5
- package/sdk-template/src/v1/generator.ts +0 -12
- package/sdk-template/tsconfig.json +0 -16
- package/src/babel.test.ts +0 -35
- package/src/babelDebugOutputs.ts +0 -56
- package/src/babelTransformRpc.ts +0 -394
- package/src/browser.ts +0 -141
- package/src/build.ts +0 -298
- package/src/cli.ts +0 -132
- package/src/context-internal.ts +0 -36
- package/src/context.ts +0 -5
- package/src/expose.ts +0 -34
- package/src/headers.ts +0 -19
- package/src/jsonRpc.ts +0 -43
- package/src/server.ts +0 -384
package/src/server.ts
DELETED
|
@@ -1,384 +0,0 @@
|
|
|
1
|
-
import { IncomingMessage, ServerResponse } from 'http';
|
|
2
|
-
import superjson from 'superjson';
|
|
3
|
-
import { asyncLocalStorage } from './context-internal.js';
|
|
4
|
-
import { JsonRpcRequest, JsonRpcResponse } from './jsonRpc.js';
|
|
5
|
-
import { jsonRpcError } from './utils.js';
|
|
6
|
-
|
|
7
|
-
export type Method<P extends any[], R> = (
|
|
8
|
-
...params: P
|
|
9
|
-
) => Promise<R> | AsyncIterable<R>;
|
|
10
|
-
export type WrapMethodMeta = {
|
|
11
|
-
name: string;
|
|
12
|
-
isGenerator: boolean;
|
|
13
|
-
pathname: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export interface WrapMethod {
|
|
17
|
-
<P extends any[], R = any>(
|
|
18
|
-
method: Method<P, R>,
|
|
19
|
-
meta: WrapMethodMeta,
|
|
20
|
-
): Method<P, R>;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export function createRpcMethod<P extends any[], R>(
|
|
24
|
-
method: Method<P, R>,
|
|
25
|
-
meta: WrapMethodMeta,
|
|
26
|
-
customWrapRpcMethod: unknown,
|
|
27
|
-
): Method<P, R> {
|
|
28
|
-
let wrapped = method;
|
|
29
|
-
if (typeof customWrapRpcMethod === 'function') {
|
|
30
|
-
wrapped = customWrapRpcMethod(method, meta);
|
|
31
|
-
if (typeof wrapped !== 'function') {
|
|
32
|
-
throw new Error(
|
|
33
|
-
`wrapMethod didn't return a function, got "${typeof wrapped}"`,
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
} else if (
|
|
37
|
-
customWrapRpcMethod !== undefined &&
|
|
38
|
-
customWrapRpcMethod !== null
|
|
39
|
-
) {
|
|
40
|
-
throw new Error(
|
|
41
|
-
`Invalid wrapMethod type, expected "function", got "${typeof customWrapRpcMethod}"`,
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
return (...args) => wrapped(...args);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
type MethodsMap = {
|
|
48
|
-
[key: string]: () => Promise<{
|
|
49
|
-
[key: string]: Method<any, any>;
|
|
50
|
-
}>;
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
export function internalEdgeHandler({
|
|
54
|
-
methodsMap,
|
|
55
|
-
}: {
|
|
56
|
-
methodsMap: MethodsMap;
|
|
57
|
-
}) {
|
|
58
|
-
return async ({ req, basePath }: { req: Request; basePath: string }) => {
|
|
59
|
-
const body = await req.json();
|
|
60
|
-
const res = new Response();
|
|
61
|
-
const result = await asyncLocalStorage.run({ req, res }, () =>
|
|
62
|
-
handler({
|
|
63
|
-
methodsMap,
|
|
64
|
-
body,
|
|
65
|
-
pathname: new URL(req.url).pathname,
|
|
66
|
-
basePath,
|
|
67
|
-
method: req.method,
|
|
68
|
-
}),
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
if (isAsyncGenerator(result)) {
|
|
72
|
-
const encoder = new TextEncoder();
|
|
73
|
-
let generatorFinished = false;
|
|
74
|
-
|
|
75
|
-
req.signal.addEventListener('abort', () => {
|
|
76
|
-
if (!generatorFinished) {
|
|
77
|
-
console.log(`request aborted, cancelling generator`);
|
|
78
|
-
result.return?.(undefined);
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
const readableStream = new ReadableStream(
|
|
82
|
-
{
|
|
83
|
-
start(controller) {},
|
|
84
|
-
async pull(controller) {
|
|
85
|
-
while (true) {
|
|
86
|
-
const { done, value } = await result.next();
|
|
87
|
-
if (done) {
|
|
88
|
-
break;
|
|
89
|
-
}
|
|
90
|
-
controller.enqueue(
|
|
91
|
-
encoder.encode('data: ' + JSON.stringify(value.json) + '\n\n'),
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
generatorFinished = true;
|
|
95
|
-
controller.close();
|
|
96
|
-
},
|
|
97
|
-
|
|
98
|
-
cancel() {},
|
|
99
|
-
},
|
|
100
|
-
// { highWaterMark: 0 },
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
return new Response(readableStream, {
|
|
104
|
-
headers: {
|
|
105
|
-
'content-type': 'text/event-stream',
|
|
106
|
-
'cache-control': 'no-cache',
|
|
107
|
-
connection: 'keep-alive',
|
|
108
|
-
},
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const { status, json } = result;
|
|
113
|
-
return new Response(JSON.stringify(json, null, 2), {
|
|
114
|
-
status,
|
|
115
|
-
headers: res?.headers || {
|
|
116
|
-
'content-type': 'application/json',
|
|
117
|
-
},
|
|
118
|
-
});
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
export function internalNodeJsHandler({
|
|
123
|
-
methodsMap,
|
|
124
|
-
}: {
|
|
125
|
-
methodsMap: MethodsMap;
|
|
126
|
-
}) {
|
|
127
|
-
return async ({
|
|
128
|
-
req,
|
|
129
|
-
res,
|
|
130
|
-
basePath,
|
|
131
|
-
}: {
|
|
132
|
-
req: IncomingMessage;
|
|
133
|
-
res: ServerResponse;
|
|
134
|
-
basePath: string;
|
|
135
|
-
}) => {
|
|
136
|
-
let body = req['body'];
|
|
137
|
-
if (body && typeof body === 'string') {
|
|
138
|
-
// if the sdk send a request without content-type header as json, it will be a string
|
|
139
|
-
body = JSON.parse(body);
|
|
140
|
-
}
|
|
141
|
-
if (!body) {
|
|
142
|
-
// if used outside of next.js, the body is not available
|
|
143
|
-
try {
|
|
144
|
-
body = await readReqJson(req);
|
|
145
|
-
} catch (error) {
|
|
146
|
-
res.writeHead(400);
|
|
147
|
-
res.end(
|
|
148
|
-
JSON.stringify(
|
|
149
|
-
jsonRpcError({ message: 'Invalid body, must be JSON' }),
|
|
150
|
-
),
|
|
151
|
-
);
|
|
152
|
-
return;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
const result = await asyncLocalStorage.run({ req, res }, () =>
|
|
157
|
-
handler({
|
|
158
|
-
methodsMap,
|
|
159
|
-
body,
|
|
160
|
-
basePath,
|
|
161
|
-
pathname: req.url!,
|
|
162
|
-
method: req.method!,
|
|
163
|
-
}),
|
|
164
|
-
);
|
|
165
|
-
|
|
166
|
-
if (isAsyncGenerator(result)) {
|
|
167
|
-
res.writeHead(200, {
|
|
168
|
-
'content-type': 'text/event-stream',
|
|
169
|
-
'cache-control': 'no-cache',
|
|
170
|
-
connection: 'keep-alive',
|
|
171
|
-
// https://github.com/vercel/next.js/issues/9965#issuecomment-584319868
|
|
172
|
-
'content-encoding': 'none',
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
let generatorFinished = false;
|
|
176
|
-
// handle cancellation
|
|
177
|
-
res.on('close', () => {
|
|
178
|
-
if (!generatorFinished) {
|
|
179
|
-
console.log(`response closed, cancelling generator`);
|
|
180
|
-
(result as AsyncIterator<any>).return?.();
|
|
181
|
-
}
|
|
182
|
-
});
|
|
183
|
-
while (true) {
|
|
184
|
-
const { done, value } = await result.next();
|
|
185
|
-
if (done) {
|
|
186
|
-
break;
|
|
187
|
-
}
|
|
188
|
-
res.write('data: ' + JSON.stringify(value.json) + '\n\n');
|
|
189
|
-
}
|
|
190
|
-
generatorFinished = true;
|
|
191
|
-
|
|
192
|
-
res.end();
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
const { status, json } = result;
|
|
196
|
-
res.writeHead(status || 200).end(JSON.stringify(json, null, 2));
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function isAsyncGenerator(obj: any): obj is AsyncGenerator<any> {
|
|
201
|
-
return obj != null && typeof obj.next === 'function';
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const handler = async ({
|
|
205
|
-
method,
|
|
206
|
-
methodsMap,
|
|
207
|
-
basePath,
|
|
208
|
-
body,
|
|
209
|
-
pathname,
|
|
210
|
-
}: {
|
|
211
|
-
method: string;
|
|
212
|
-
basePath: string;
|
|
213
|
-
pathname: string;
|
|
214
|
-
methodsMap: MethodsMap;
|
|
215
|
-
body: JsonRpcRequest;
|
|
216
|
-
}) => {
|
|
217
|
-
if (!methodsMap) {
|
|
218
|
-
throw new Error('No methods found');
|
|
219
|
-
}
|
|
220
|
-
if (basePath && pathname.startsWith(basePath)) {
|
|
221
|
-
if (basePath.endsWith('/')) {
|
|
222
|
-
basePath = basePath.slice(0, -1);
|
|
223
|
-
}
|
|
224
|
-
pathname = pathname.slice(basePath.length);
|
|
225
|
-
}
|
|
226
|
-
if (method !== 'POST') {
|
|
227
|
-
return {
|
|
228
|
-
status: 405,
|
|
229
|
-
json: {
|
|
230
|
-
jsonrpc: '2.0',
|
|
231
|
-
id: null,
|
|
232
|
-
error: {
|
|
233
|
-
code: -32001,
|
|
234
|
-
message: 'Server error',
|
|
235
|
-
data: {
|
|
236
|
-
cause: `HTTP method "${method}" is not allowed`,
|
|
237
|
-
},
|
|
238
|
-
},
|
|
239
|
-
} satisfies JsonRpcResponse,
|
|
240
|
-
};
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
const { id, method: fn, params, meta: argsMeta } = body;
|
|
244
|
-
|
|
245
|
-
const mod = methodsMap[pathname] && (await methodsMap[pathname]());
|
|
246
|
-
if (!mod) {
|
|
247
|
-
return {
|
|
248
|
-
status: 400,
|
|
249
|
-
json: {
|
|
250
|
-
jsonrpc: '2.0',
|
|
251
|
-
id,
|
|
252
|
-
error: {
|
|
253
|
-
code: -32601,
|
|
254
|
-
message: 'Method not found',
|
|
255
|
-
data: {
|
|
256
|
-
cause: `Path "${pathname}" is not handled by any method`,
|
|
257
|
-
},
|
|
258
|
-
},
|
|
259
|
-
} satisfies JsonRpcResponse,
|
|
260
|
-
};
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
const requestedMethod = mod[fn];
|
|
264
|
-
|
|
265
|
-
if (typeof requestedMethod !== 'function') {
|
|
266
|
-
return {
|
|
267
|
-
status: 400,
|
|
268
|
-
json: {
|
|
269
|
-
jsonrpc: '2.0',
|
|
270
|
-
id,
|
|
271
|
-
error: {
|
|
272
|
-
code: -32601,
|
|
273
|
-
message: 'Method not found',
|
|
274
|
-
data: {
|
|
275
|
-
cause: `Method "${fn}" is not a function, in ${Object.keys(
|
|
276
|
-
mod,
|
|
277
|
-
).join(', ')}`,
|
|
278
|
-
},
|
|
279
|
-
},
|
|
280
|
-
} satisfies JsonRpcResponse,
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
try {
|
|
285
|
-
const args = superjson.deserialize({
|
|
286
|
-
json: params,
|
|
287
|
-
meta: argsMeta,
|
|
288
|
-
}) as any[];
|
|
289
|
-
const result = await requestedMethod(...args);
|
|
290
|
-
if (!isAsyncGenerator(result)) {
|
|
291
|
-
const { json, meta } = superjson.serialize(result);
|
|
292
|
-
|
|
293
|
-
return {
|
|
294
|
-
json: {
|
|
295
|
-
jsonrpc: '2.0',
|
|
296
|
-
id,
|
|
297
|
-
result: json as any,
|
|
298
|
-
meta,
|
|
299
|
-
} satisfies JsonRpcResponse,
|
|
300
|
-
};
|
|
301
|
-
}
|
|
302
|
-
return (async function* () {
|
|
303
|
-
// send a response for each yielded value
|
|
304
|
-
|
|
305
|
-
try {
|
|
306
|
-
while (true) {
|
|
307
|
-
const { done, value } = await result.next();
|
|
308
|
-
if (done) {
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
const { json, meta } = superjson.serialize(value);
|
|
312
|
-
|
|
313
|
-
yield {
|
|
314
|
-
json: {
|
|
315
|
-
jsonrpc: '2.0',
|
|
316
|
-
id,
|
|
317
|
-
result: json as any,
|
|
318
|
-
meta,
|
|
319
|
-
} satisfies JsonRpcResponse,
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
} catch (error) {
|
|
323
|
-
const {
|
|
324
|
-
name = 'RpcError',
|
|
325
|
-
message = `Invalid value thrown in "${method}", must be instance of Error`,
|
|
326
|
-
stack = undefined,
|
|
327
|
-
} = error instanceof Error ? error : {};
|
|
328
|
-
return {
|
|
329
|
-
json: {
|
|
330
|
-
jsonrpc: '2.0',
|
|
331
|
-
id,
|
|
332
|
-
error: {
|
|
333
|
-
code: 1,
|
|
334
|
-
message,
|
|
335
|
-
data: {
|
|
336
|
-
name,
|
|
337
|
-
...(process.env.NODE_ENV === 'production' ? {} : { stack }),
|
|
338
|
-
},
|
|
339
|
-
},
|
|
340
|
-
} satisfies JsonRpcResponse,
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
})();
|
|
344
|
-
} catch (error) {
|
|
345
|
-
const {
|
|
346
|
-
name = 'RpcError',
|
|
347
|
-
message = `Invalid value thrown in "${method}", must be instance of Error`,
|
|
348
|
-
stack = undefined,
|
|
349
|
-
} = error instanceof Error ? error : {};
|
|
350
|
-
return {
|
|
351
|
-
status: 502,
|
|
352
|
-
json: {
|
|
353
|
-
jsonrpc: '2.0',
|
|
354
|
-
id,
|
|
355
|
-
error: {
|
|
356
|
-
code: 1,
|
|
357
|
-
message,
|
|
358
|
-
data: {
|
|
359
|
-
name,
|
|
360
|
-
...(process.env.NODE_ENV === 'production' ? {} : { stack }),
|
|
361
|
-
},
|
|
362
|
-
},
|
|
363
|
-
} satisfies JsonRpcResponse,
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
function readReqJson(req: IncomingMessage) {
|
|
369
|
-
return new Promise((resolve, reject) => {
|
|
370
|
-
let data = '';
|
|
371
|
-
req.on('data', (chunk) => {
|
|
372
|
-
data += chunk;
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
req.on('end', () => {
|
|
376
|
-
try {
|
|
377
|
-
const parsedData = JSON.parse(data);
|
|
378
|
-
resolve(parsedData);
|
|
379
|
-
} catch (error) {
|
|
380
|
-
reject(error);
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
});
|
|
384
|
-
}
|