@milkio/stargate 1.0.0-alpha.1 → 1.0.0-alpha.100
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/.publish/publish.json +0 -0
- package/README.md +0 -0
- package/index.ts +128 -60
- package/package.json +2 -5
- package/tsconfig.json +9 -8
package/.publish/publish.json
CHANGED
|
File without changes
|
package/README.md
CHANGED
|
File without changes
|
package/index.ts
CHANGED
|
@@ -40,6 +40,64 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
40
40
|
const $fetch = stargateOptions.fetch ?? fetch;
|
|
41
41
|
const $abort = stargateOptions.abort ?? AbortController;
|
|
42
42
|
|
|
43
|
+
type StargateEvents = {
|
|
44
|
+
"milkio:executeBefore": { path: string; options: Mixin<ExecuteOptions, { headers: Record<string, string>; baseUrl: string }> };
|
|
45
|
+
"milkio:fetchBefore": { path: string; options: Mixin<ExecuteOptions, { headers: Record<string, string>; baseUrl: string }>; body: string };
|
|
46
|
+
"milkio:executeError": {
|
|
47
|
+
path: string;
|
|
48
|
+
options: Mixin<ExecuteOptions, { headers: Record<string, string>; baseUrl: string }>;
|
|
49
|
+
error: Partial<Generated["rejectCode"]>;
|
|
50
|
+
handleError: <K extends keyof Partial<Generated["rejectCode"]>>(error: any, key: K, handler: (error: Partial<Generated["rejectCode"][K]>) => boolean | Promise<boolean>) => Promise<void>;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const handleError: any = async (error: any, key: string, handler: (error: any) => boolean | Promise<boolean>) => {
|
|
55
|
+
if (key in error) {
|
|
56
|
+
const handled = await handler(error[key]);
|
|
57
|
+
if (handled) delete error[key];
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const __initEventManager = () => {
|
|
62
|
+
const handlers = new Map<(event: any) => void, string>();
|
|
63
|
+
const indexed = new Map<string, Set<(event: any) => void>>();
|
|
64
|
+
|
|
65
|
+
const eventManager = {
|
|
66
|
+
on: <Key extends keyof StargateEvents, Handler extends (event: StargateEvents[Key]) => void>(key: Key, handler: Handler) => {
|
|
67
|
+
handlers.set(handler, key as string);
|
|
68
|
+
if (indexed.has(key as string) === false) {
|
|
69
|
+
indexed.set(key as string, new Set());
|
|
70
|
+
}
|
|
71
|
+
const set = indexed.get(key as string)!;
|
|
72
|
+
set.add(handler);
|
|
73
|
+
handlers.set(handler, key as string);
|
|
74
|
+
|
|
75
|
+
return () => {
|
|
76
|
+
handlers.delete(handler);
|
|
77
|
+
set.delete(handler);
|
|
78
|
+
};
|
|
79
|
+
},
|
|
80
|
+
off: <Key extends keyof StargateEvents, Handler extends (event: StargateEvents[Key]) => void>(key: Key, handler: Handler) => {
|
|
81
|
+
const set = indexed.get(key as string);
|
|
82
|
+
if (!set) return;
|
|
83
|
+
handlers.delete(handler);
|
|
84
|
+
set.delete(handler);
|
|
85
|
+
},
|
|
86
|
+
emit: async <Key extends keyof StargateEvents, Value extends StargateEvents[Key]>(key: Key, value: Value): Promise<void> => {
|
|
87
|
+
const h = indexed.get(key as string);
|
|
88
|
+
if (h) {
|
|
89
|
+
for (const handler of h) {
|
|
90
|
+
await handler(value);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return eventManager;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const eventManager = __initEventManager();
|
|
100
|
+
|
|
43
101
|
const bootstrap = async () => {
|
|
44
102
|
let baseUrl = stargateOptions.baseUrl;
|
|
45
103
|
if (typeof baseUrl === "function") baseUrl = await baseUrl();
|
|
@@ -51,25 +109,27 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
51
109
|
const baseUrl: Promise<string> = bootstrap();
|
|
52
110
|
|
|
53
111
|
const stargate = {
|
|
112
|
+
...eventManager,
|
|
54
113
|
$types: {
|
|
55
114
|
generated: void 0 as unknown as Generated,
|
|
56
115
|
},
|
|
57
116
|
options: stargateOptions,
|
|
58
|
-
async execute<Path extends keyof Generated["routeSchema"]
|
|
117
|
+
async execute<Path extends keyof Generated["routeSchema"]>(
|
|
59
118
|
path: Path,
|
|
60
119
|
options?: Mixin<
|
|
61
120
|
ExecuteOptions,
|
|
62
121
|
{
|
|
63
|
-
params?: Generated["routeSchema"]["
|
|
122
|
+
params?: Generated["routeSchema"][Path]["types"]["params"];
|
|
64
123
|
}
|
|
65
124
|
>,
|
|
66
125
|
): Promise<
|
|
67
|
-
Generated["routeSchema"]["
|
|
126
|
+
Generated["routeSchema"][Path]["types"]["🐣"] extends boolean
|
|
68
127
|
? // action
|
|
69
|
-
[Partial<Generated["rejectCode"]>, null, ExecuteResultsOption] | [null, Generated["routeSchema"]["
|
|
128
|
+
[Partial<Generated["rejectCode"]>, null, ExecuteResultsOption] | [null, Generated["routeSchema"][Path]["types"]["result"], ExecuteResultsOption]
|
|
70
129
|
: // stream
|
|
71
|
-
[Partial<Generated["rejectCode"]>, null, ExecuteResultsOption] | [null, AsyncGenerator<[Partial<Generated["rejectCode"]>, null] | [null, GeneratorGeneric<Generated["routeSchema"]["
|
|
130
|
+
[Partial<Generated["rejectCode"]>, null, ExecuteResultsOption] | [null, AsyncGenerator<[Partial<Generated["rejectCode"]>, null] | [null, GeneratorGeneric<Generated["routeSchema"][Path]["types"]["result"]>], ExecuteResultsOption>]
|
|
72
131
|
> {
|
|
132
|
+
// biome-ignore lint/style/noParameterAssign: <explanation>
|
|
73
133
|
if (!options) options = {};
|
|
74
134
|
if (options.headers === undefined) options.headers = {};
|
|
75
135
|
|
|
@@ -79,17 +139,23 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
79
139
|
if (typeof baseUrl === "function") baseUrl = await baseUrl();
|
|
80
140
|
if (baseUrl.endsWith("/")) baseUrl = baseUrl.slice(0, -1);
|
|
81
141
|
url = baseUrl + (path as string);
|
|
82
|
-
} else
|
|
142
|
+
} else {
|
|
143
|
+
url = (await baseUrl) + (path as string);
|
|
144
|
+
}
|
|
83
145
|
|
|
84
146
|
if (options.type !== "stream") {
|
|
85
147
|
// action
|
|
86
|
-
if (options.headers
|
|
148
|
+
if (options.headers.Accept === undefined) options.headers.Accept = "application/json";
|
|
87
149
|
if (options.headers["Content-Type"] === undefined) options.headers["Content-Type"] = "application/json";
|
|
88
|
-
|
|
89
|
-
const body = TSON.stringify(options.params) ?? "";
|
|
90
|
-
|
|
91
150
|
let result: { value: Record<any, any> };
|
|
151
|
+
|
|
92
152
|
try {
|
|
153
|
+
await eventManager.emit("milkio:executeBefore", { path: path as string, options: options as any });
|
|
154
|
+
|
|
155
|
+
const body = TSON.stringify(options.params) ?? "";
|
|
156
|
+
await eventManager.emit("milkio:fetchBefore", { path: path as string, options: options as any, body });
|
|
157
|
+
|
|
158
|
+
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: <explanation>
|
|
93
159
|
const response = await new Promise<string>(async (resolve, reject) => {
|
|
94
160
|
const timeout = options?.timeout ?? options?.timeout ?? 6000;
|
|
95
161
|
const timer = setTimeout(() => {
|
|
@@ -106,22 +172,27 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
106
172
|
});
|
|
107
173
|
result = { value: TSON.parse(response) };
|
|
108
174
|
} catch (error: any) {
|
|
109
|
-
if (error?.[0]?.REQUEST_TIMEOUT)
|
|
110
|
-
|
|
175
|
+
if (error?.[0]?.REQUEST_TIMEOUT) {
|
|
176
|
+
await eventManager.emit("milkio:executeError", { handleError, path: path as string, options: options as any, error });
|
|
177
|
+
return error;
|
|
178
|
+
}
|
|
179
|
+
const errorPined = { REQUEST_FAIL: error };
|
|
180
|
+
await eventManager.emit("milkio:executeError", { handleError, path: path as string, options: options as any, error: errorPined });
|
|
181
|
+
return [errorPined, null, { executeId: "unknown" }];
|
|
111
182
|
}
|
|
112
183
|
if (result.value.success !== true) {
|
|
113
184
|
const error: any = {};
|
|
114
|
-
error[result.value.code] = result.value.reject;
|
|
185
|
+
error[result.value.code] = result.value.reject ?? null;
|
|
186
|
+
await eventManager.emit("milkio:executeError", { handleError, path: path as string, options: options as any, error });
|
|
115
187
|
return [error, null, { executeId: "unknown" }];
|
|
116
188
|
}
|
|
117
189
|
|
|
118
190
|
return [null, result.value.data, { executeId: result.value.executeId }] as any;
|
|
119
191
|
} else {
|
|
120
192
|
// stream
|
|
121
|
-
if (options.headers
|
|
193
|
+
if (options.headers.Accept === undefined) options.headers.Accept = "text/event-stream";
|
|
122
194
|
if (options.headers["Content-Type"] === undefined) options.headers["Content-Type"] = "application/json";
|
|
123
195
|
|
|
124
|
-
const body = TSON.stringify(options.params) ?? "";
|
|
125
196
|
const stacks: Map<
|
|
126
197
|
number,
|
|
127
198
|
{
|
|
@@ -131,10 +202,10 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
131
202
|
reject: (reason: any) => void;
|
|
132
203
|
}
|
|
133
204
|
> = new Map();
|
|
134
|
-
let stacksIndex
|
|
135
|
-
let iteratorIndex
|
|
136
|
-
let streamResult: any
|
|
137
|
-
|
|
205
|
+
let stacksIndex = 0;
|
|
206
|
+
let iteratorIndex = 0;
|
|
207
|
+
let streamResult: any;
|
|
208
|
+
const streamResultFetched = withResolvers<undefined>();
|
|
138
209
|
|
|
139
210
|
const timeout = stargateOptions?.timeout ?? options?.timeout ?? 6000;
|
|
140
211
|
const timer = setTimeout(() => {
|
|
@@ -151,7 +222,6 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
151
222
|
streamResultFetched.reject([{ REQUEST_FAIL: error }, null, { executeId: "unknown" }]);
|
|
152
223
|
clearTimeout(timer);
|
|
153
224
|
}
|
|
154
|
-
return;
|
|
155
225
|
} else {
|
|
156
226
|
const index = ++stacksIndex;
|
|
157
227
|
if (stacks.has(index)) {
|
|
@@ -174,10 +244,15 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
174
244
|
iterator.return();
|
|
175
245
|
});
|
|
176
246
|
try {
|
|
247
|
+
await eventManager.emit("milkio:executeBefore", { path: path as string, options: options as any });
|
|
248
|
+
|
|
249
|
+
const body = TSON.stringify(options!.params) ?? "";
|
|
250
|
+
await eventManager.emit("milkio:fetchBefore", { path: path as string, options: options as any, body });
|
|
251
|
+
|
|
177
252
|
const response = await $fetch(url, {
|
|
178
253
|
method: "POST",
|
|
179
254
|
headers: options!.headers,
|
|
180
|
-
body
|
|
255
|
+
body,
|
|
181
256
|
signal: curRequestController.signal,
|
|
182
257
|
});
|
|
183
258
|
|
|
@@ -188,15 +263,13 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
188
263
|
|
|
189
264
|
await getBytes(response.body!, getLines(getMessages(onmessage)));
|
|
190
265
|
|
|
191
|
-
// for (const m of _afterExecuteMiddlewares) {
|
|
192
|
-
// await m.middleware({ path: path as string, storage: options.storage as ClientStorage, result: { value: undefined } });
|
|
193
|
-
// }
|
|
194
|
-
|
|
195
266
|
await iterator.return();
|
|
196
267
|
} catch (err) {
|
|
197
268
|
if (!curRequestController.signal.aborted) curRequestController.abort();
|
|
269
|
+
const error = { REQUEST_FAIL: err };
|
|
270
|
+
await eventManager.emit("milkio:executeError", { handleError, path: path as string, options: options as any, error });
|
|
198
271
|
await iterator.throw(err);
|
|
199
|
-
streamResultFetched.reject([
|
|
272
|
+
streamResultFetched.reject([error, null, { executeId: "unknown" }]);
|
|
200
273
|
}
|
|
201
274
|
}
|
|
202
275
|
|
|
@@ -258,7 +331,7 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
258
331
|
}
|
|
259
332
|
}
|
|
260
333
|
},
|
|
261
|
-
|
|
334
|
+
__cookbook: {
|
|
262
335
|
subscribe: async (baseUrl: string) => {
|
|
263
336
|
const headers = {
|
|
264
337
|
"Content-Type": "application/json",
|
|
@@ -276,8 +349,8 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
276
349
|
reject: (reason: any) => void;
|
|
277
350
|
}
|
|
278
351
|
> = new Map();
|
|
279
|
-
let stacksIndex
|
|
280
|
-
let iteratorIndex
|
|
352
|
+
let stacksIndex = 0;
|
|
353
|
+
let iteratorIndex = 0;
|
|
281
354
|
|
|
282
355
|
const onmessage = (event: EventSourceMessage) => {
|
|
283
356
|
const index = ++stacksIndex;
|
|
@@ -301,8 +374,8 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
301
374
|
try {
|
|
302
375
|
const response = await $fetch(`${baseUrl}/$subscribe`, {
|
|
303
376
|
method: "POST",
|
|
304
|
-
headers
|
|
305
|
-
body
|
|
377
|
+
headers,
|
|
378
|
+
body,
|
|
306
379
|
signal: curRequestController.signal,
|
|
307
380
|
});
|
|
308
381
|
|
|
@@ -363,10 +436,11 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
363
436
|
},
|
|
364
437
|
},
|
|
365
438
|
async ping(options?: { timeout?: number }): Promise<Ping> {
|
|
439
|
+
// biome-ignore lint/suspicious/noAsyncPromiseExecutor: <explanation>
|
|
366
440
|
return await new Promise<Ping>(async (resolve) => {
|
|
367
|
-
const url =
|
|
441
|
+
const url = `${await baseUrl}/generate_204`;
|
|
368
442
|
const timeout = stargateOptions?.timeout ?? options?.timeout ?? 6000;
|
|
369
|
-
|
|
443
|
+
const startsTime = Date.now();
|
|
370
444
|
const timer = setTimeout(() => {
|
|
371
445
|
const endsTime = Date.now();
|
|
372
446
|
resolve([{ connect: false, delay: endsTime - startsTime, error: { REQUEST_TIMEOUT: { timeout, message: `Execute timeout after ${timeout}ms.` } } }, null]);
|
|
@@ -377,13 +451,13 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
377
451
|
const endsTime = Date.now();
|
|
378
452
|
clearTimeout(timer);
|
|
379
453
|
if (response.status !== 204) {
|
|
380
|
-
resolve([{ connect: false, delay: endsTime - startsTime, error: { REQUEST_FAIL: { response, status: response.status, message:
|
|
454
|
+
resolve([{ connect: false, delay: endsTime - startsTime, error: { REQUEST_FAIL: { response, status: response.status, message: "Status code not 204" } } }, null]);
|
|
381
455
|
}
|
|
382
456
|
|
|
383
457
|
resolve([null, { connect: true, delay: endsTime - startsTime, serverTimestamp: Number(response.headers.get("Content-Type")!.substring(17)) }]);
|
|
384
458
|
} catch (error: any) {
|
|
385
459
|
const endsTime = Date.now();
|
|
386
|
-
return [{ connect: false, delay: endsTime - startsTime, error
|
|
460
|
+
return [{ connect: false, delay: endsTime - startsTime, error }, null];
|
|
387
461
|
}
|
|
388
462
|
});
|
|
389
463
|
},
|
|
@@ -392,12 +466,12 @@ export async function createStargate<Generated extends { routeSchema: any; rejec
|
|
|
392
466
|
return stargate;
|
|
393
467
|
}
|
|
394
468
|
|
|
395
|
-
export
|
|
469
|
+
export interface ExecuteStreamOptions {
|
|
396
470
|
headers?: Record<string, string>;
|
|
397
471
|
timeout?: number;
|
|
398
|
-
}
|
|
472
|
+
}
|
|
399
473
|
|
|
400
|
-
export
|
|
474
|
+
export interface ApiSchemaExtend {
|
|
401
475
|
apiValidator: {
|
|
402
476
|
generatedAt: number;
|
|
403
477
|
validate: Record<any, any>;
|
|
@@ -405,7 +479,7 @@ export type ApiSchemaExtend = {
|
|
|
405
479
|
apiMethodsSchema: Record<any, any>;
|
|
406
480
|
apiMethodsTypeSchema: Record<any, any>;
|
|
407
481
|
apiTestsSchema: Record<any, any>;
|
|
408
|
-
}
|
|
482
|
+
}
|
|
409
483
|
|
|
410
484
|
export type FailCodeExtend = Record<any, (...args: Array<any>) => any>;
|
|
411
485
|
|
|
@@ -413,27 +487,27 @@ export type BootstrapMiddleware = (data: { storage: ClientStorage }) => Promise<
|
|
|
413
487
|
export type BeforeExecuteMiddleware = (data: { path: string; params: any; headers: Record<string, string>; storage: ClientStorage }) => Promise<void> | void;
|
|
414
488
|
export type AfterExecuteMiddleware = (data: { path: string; result: { value: any }; storage: ClientStorage }) => Promise<void> | void;
|
|
415
489
|
|
|
416
|
-
export
|
|
490
|
+
export interface MiddlewareOptions {
|
|
417
491
|
bootstrap?: BootstrapMiddleware;
|
|
418
492
|
beforeExecute?: BeforeExecuteMiddleware;
|
|
419
493
|
afterExecute?: AfterExecuteMiddleware;
|
|
420
|
-
}
|
|
494
|
+
}
|
|
421
495
|
|
|
422
|
-
export
|
|
496
|
+
export interface ClientStorage {
|
|
423
497
|
getItem: (key: string) => Promise<string | null>;
|
|
424
498
|
setItem: (key: string, value: string) => Promise<void>;
|
|
425
499
|
removeItem: (key: string) => Promise<void>;
|
|
426
|
-
}
|
|
500
|
+
}
|
|
427
501
|
|
|
428
|
-
export
|
|
502
|
+
export interface ExecuteResultSuccess<Result> {
|
|
429
503
|
executeId: string;
|
|
430
504
|
success: true;
|
|
431
505
|
data: Result;
|
|
432
|
-
}
|
|
506
|
+
}
|
|
433
507
|
|
|
434
508
|
export type GeneratorGeneric<T> = T extends AsyncGenerator<infer I> ? I : never;
|
|
435
509
|
|
|
436
|
-
export type FlattenKeys<T
|
|
510
|
+
export type FlattenKeys<T, Prefix extends string = ""> = {
|
|
437
511
|
[K in keyof T]: T[K] extends object ? FlattenKeys<T[K], `${Prefix}${Exclude<K, symbol>}.`> : `$input.${Prefix}${Exclude<K, symbol>}`;
|
|
438
512
|
}[keyof T];
|
|
439
513
|
|
|
@@ -457,18 +531,12 @@ export interface EventSourceMessage {
|
|
|
457
531
|
export async function getBytes(stream: ReadableStream<Uint8Array>, onChunk: (arr: Uint8Array) => void) {
|
|
458
532
|
const reader = stream.getReader();
|
|
459
533
|
let result: ReadableStreamReadResult<Uint8Array>;
|
|
534
|
+
// biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
|
|
460
535
|
while (!(result = await reader.read()).done) {
|
|
461
536
|
onChunk(result.value);
|
|
462
537
|
}
|
|
463
538
|
}
|
|
464
539
|
|
|
465
|
-
const enum ControlChars {
|
|
466
|
-
NewLine = 10,
|
|
467
|
-
CarriageReturn = 13,
|
|
468
|
-
Space = 32,
|
|
469
|
-
Colon = 58,
|
|
470
|
-
}
|
|
471
|
-
|
|
472
540
|
/**
|
|
473
541
|
* Parses arbitary byte chunks into EventSource line buffers.
|
|
474
542
|
* Each line should be of the format "field: value" and ends with \r, \n, or \r\n.
|
|
@@ -496,7 +564,7 @@ export function getLines(onLine: (line: Uint8Array, fieldLength: number) => void
|
|
|
496
564
|
let lineStart = 0; // index where the current line starts
|
|
497
565
|
while (position < bufLength) {
|
|
498
566
|
if (discardTrailingNewline) {
|
|
499
|
-
if (buffer[position] ===
|
|
567
|
+
if (buffer[position] === 10) {
|
|
500
568
|
lineStart = ++position; // skip to next char
|
|
501
569
|
}
|
|
502
570
|
|
|
@@ -507,16 +575,16 @@ export function getLines(onLine: (line: Uint8Array, fieldLength: number) => void
|
|
|
507
575
|
let lineEnd = -1; // index of the \r or \n char
|
|
508
576
|
for (; position < bufLength && lineEnd === -1; ++position) {
|
|
509
577
|
switch (buffer[position]) {
|
|
510
|
-
case
|
|
578
|
+
case 58:
|
|
511
579
|
if (fieldLength === -1) {
|
|
512
580
|
// first colon in line
|
|
513
581
|
fieldLength = position - lineStart;
|
|
514
582
|
}
|
|
515
583
|
break;
|
|
516
|
-
//
|
|
517
|
-
case
|
|
584
|
+
// biome-ignore lint/suspicious/noFallthroughSwitchClause: <explanation>
|
|
585
|
+
case 13:
|
|
518
586
|
discardTrailingNewline = true;
|
|
519
|
-
case
|
|
587
|
+
case 10:
|
|
520
588
|
lineEnd = position;
|
|
521
589
|
break;
|
|
522
590
|
}
|
|
@@ -567,14 +635,14 @@ export function getMessages(onMessage?: (msg: EventSourceMessage) => void) {
|
|
|
567
635
|
// line is of format "<field>:<value>" or "<field>: <value>"
|
|
568
636
|
// https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation
|
|
569
637
|
const field = decoder.decode(line.subarray(0, fieldLength));
|
|
570
|
-
const valueOffset = fieldLength + (line[fieldLength + 1] ===
|
|
638
|
+
const valueOffset = fieldLength + (line[fieldLength + 1] === 32 ? 2 : 1);
|
|
571
639
|
const value = decoder.decode(line.subarray(valueOffset));
|
|
572
640
|
|
|
573
641
|
switch (field) {
|
|
574
642
|
case "data":
|
|
575
643
|
// if this message already has data, append the new value to the old.
|
|
576
644
|
// otherwise, just set to the new value:
|
|
577
|
-
message.data = message.data ? message.data
|
|
645
|
+
message.data = message.data ? `${message.data}\n${value}` : value; // otherwise,
|
|
578
646
|
break;
|
|
579
647
|
}
|
|
580
648
|
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@milkio/stargate",
|
|
3
|
-
"module": "index.ts",
|
|
4
|
-
"version": "1.0.0-alpha.1",
|
|
5
3
|
"type": "module",
|
|
4
|
+
"version": "1.0.0-alpha.100",
|
|
5
|
+
"module": "index.ts",
|
|
6
6
|
"dependencies": {
|
|
7
7
|
"@southern-aurora/tson": "^2.0.2"
|
|
8
8
|
},
|
|
9
9
|
"devDependencies": {
|
|
10
10
|
"@types/bun": "latest"
|
|
11
|
-
},
|
|
12
|
-
"peerDependencies": {
|
|
13
|
-
"typescript": "5.6.0"
|
|
14
11
|
}
|
|
15
12
|
}
|
package/tsconfig.json
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"jsx": "react-jsx",
|
|
5
|
+
"erasableSyntaxOnly":true,
|
|
3
6
|
// Enable latest features
|
|
4
7
|
"lib": ["ESNext", "DOM"],
|
|
5
|
-
"target": "ESNext",
|
|
6
|
-
"module": "ESNext",
|
|
7
8
|
"moduleDetection": "force",
|
|
8
|
-
"
|
|
9
|
-
"allowJs": true,
|
|
9
|
+
"module": "ESNext",
|
|
10
10
|
|
|
11
11
|
// Bundler mode
|
|
12
12
|
"moduleResolution": "bundler",
|
|
13
13
|
"allowImportingTsExtensions": true,
|
|
14
|
-
"
|
|
15
|
-
"noEmit": true,
|
|
14
|
+
"allowJs": true,
|
|
16
15
|
|
|
17
16
|
// Best practices
|
|
18
17
|
"strict": true,
|
|
19
|
-
"skipLibCheck": true,
|
|
20
18
|
"noFallthroughCasesInSwitch": true,
|
|
21
19
|
|
|
20
|
+
"noPropertyAccessFromIndexSignature": false,
|
|
22
21
|
// Some stricter flags (disabled by default)
|
|
23
22
|
"noUnusedLocals": false,
|
|
24
23
|
"noUnusedParameters": false,
|
|
25
|
-
"
|
|
24
|
+
"noEmit": true,
|
|
25
|
+
"verbatimModuleSyntax": true,
|
|
26
|
+
"skipLibCheck": true
|
|
26
27
|
}
|
|
27
28
|
}
|