@requence/service 0.8.2-edge.1155 → 0.8.2-edge.1157
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 +163 -0
- package/build/index.js +289 -50
- package/build/index.js.map +13 -11
- package/build/types/helpers/src/utils/requenceCallback.d.ts +153 -3
- package/build/types/helpers/src/utils/requenceCallback.d.ts.map +1 -1
- package/build/types/service/src/boundary.d.ts +9 -0
- package/build/types/service/src/boundary.d.ts.map +1 -1
- package/build/types/service/src/callbackGrowth.d.ts +102 -0
- package/build/types/service/src/callbackGrowth.d.ts.map +1 -0
- package/build/types/service/src/createAmqpConnection.d.ts +1 -0
- package/build/types/service/src/createAmqpConnection.d.ts.map +1 -1
- package/build/types/service/src/durableCallback.d.ts +223 -0
- package/build/types/service/src/durableCallback.d.ts.map +1 -0
- package/build/types/service/src/helpers.d.ts +6 -5
- package/build/types/service/src/helpers.d.ts.map +1 -1
- package/build/types/service/src/index.d.ts +1 -0
- package/build/types/service/src/index.d.ts.map +1 -1
- package/build/types/service/src/surfaceHandler.d.ts.map +1 -1
- package/build/types/service/src/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/build/index.js
CHANGED
|
@@ -178,13 +178,27 @@ function isClaimCheckObject(data) {
|
|
|
178
178
|
|
|
179
179
|
// ../helpers/src/utils/requenceCallback.ts
|
|
180
180
|
import { z as z5 } from "zod/v4";
|
|
181
|
-
var
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
181
|
+
var REQUENCE_CALLBACK_TAG = "RequenceCallback";
|
|
182
|
+
var callbackPathSchema = z5.array(z5.union([z5.string(), z5.int()]));
|
|
183
|
+
var callbackObjectSchema = z5.discriminatedUnion("lifetime", [
|
|
184
|
+
z5.object({
|
|
185
|
+
__REQUENCE_type: z5.literal(REQUENCE_CALLBACK_TAG),
|
|
186
|
+
lifetime: z5.literal("connection"),
|
|
187
|
+
outputName: z5.string().nullable(),
|
|
188
|
+
propertyPath: callbackPathSchema,
|
|
189
|
+
sourceId: z5.string(),
|
|
190
|
+
callbackId: z5.uuid()
|
|
191
|
+
}),
|
|
192
|
+
z5.object({
|
|
193
|
+
__REQUENCE_type: z5.literal(REQUENCE_CALLBACK_TAG),
|
|
194
|
+
lifetime: z5.literal("durable"),
|
|
195
|
+
outputName: z5.string().nullable(),
|
|
196
|
+
propertyPath: callbackPathSchema,
|
|
197
|
+
name: z5.string(),
|
|
198
|
+
nodeId: z5.string(),
|
|
199
|
+
bound: z5.unknown().optional()
|
|
200
|
+
})
|
|
201
|
+
]);
|
|
188
202
|
function isCallbackObject(data) {
|
|
189
203
|
return callbackObjectSchema.safeParse(data).success;
|
|
190
204
|
}
|
|
@@ -200,6 +214,43 @@ function createCallback(callback) {
|
|
|
200
214
|
}
|
|
201
215
|
});
|
|
202
216
|
}
|
|
217
|
+
var DURABLE_CALLBACK_BINDING = Symbol.for("requence.durableCallbackBinding");
|
|
218
|
+
function createDurableCallbackReference(binding) {
|
|
219
|
+
const reference = () => {
|
|
220
|
+
throw new Error(`durable callback "${binding.name}" was called in the service that emitted it — a durable callback reference is a value to emit, and it runs only when the graph invokes it`);
|
|
221
|
+
};
|
|
222
|
+
Object.defineProperty(reference, "name", {
|
|
223
|
+
value: binding.name,
|
|
224
|
+
configurable: true
|
|
225
|
+
});
|
|
226
|
+
return Object.defineProperty(reference, DURABLE_CALLBACK_BINDING, {
|
|
227
|
+
value: binding,
|
|
228
|
+
enumerable: false
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
function readDurableCallbackBinding(value) {
|
|
232
|
+
if (typeof value !== "function") {
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
const binding = value[DURABLE_CALLBACK_BINDING];
|
|
236
|
+
return typeof binding === "object" && binding !== null && typeof binding.name === "string" ? binding : undefined;
|
|
237
|
+
}
|
|
238
|
+
function serviceCallbackQueueName(dispatchQueue) {
|
|
239
|
+
return `${dispatchQueue}-callbacks`;
|
|
240
|
+
}
|
|
241
|
+
var DURABLE_CALLBACK_INVOCATION_TTL_MS = 60000;
|
|
242
|
+
var DURABLE_CALLBACK_QUEUE_ARGUMENTS = {
|
|
243
|
+
messageTtl: DURABLE_CALLBACK_INVOCATION_TTL_MS,
|
|
244
|
+
deadLetterExchange: "error"
|
|
245
|
+
};
|
|
246
|
+
var durableCallbackInvocationSchema = z5.object({
|
|
247
|
+
taskId: z5.uuid(),
|
|
248
|
+
nodeId: z5.string(),
|
|
249
|
+
name: z5.string(),
|
|
250
|
+
bound: z5.unknown().optional(),
|
|
251
|
+
arg: z5.unknown().optional(),
|
|
252
|
+
configuration: z5.unknown().optional()
|
|
253
|
+
});
|
|
203
254
|
|
|
204
255
|
// ../helpers/src/utils/serviceRender.ts
|
|
205
256
|
import { z as z6 } from "zod/v4";
|
|
@@ -995,17 +1046,33 @@ function sanitizeLogData(data) {
|
|
|
995
1046
|
// ../callbacks/src/handler.ts
|
|
996
1047
|
function createRequenceCallbackHandler() {
|
|
997
1048
|
return {
|
|
998
|
-
tag:
|
|
1049
|
+
tag: REQUENCE_CALLBACK_TAG,
|
|
999
1050
|
canHandle: (value) => typeof value === "function",
|
|
1000
1051
|
serialize(callback, ctx, path) {
|
|
1052
|
+
const binding = readDurableCallbackBinding(callback);
|
|
1053
|
+
if (binding) {
|
|
1054
|
+
if (!ctx.nodeId) {
|
|
1055
|
+
throw new Error(`durable callback "${binding.name}" cannot be emitted on this boundary (no ctx.nodeId) at path "${path.join(".")}"`);
|
|
1056
|
+
}
|
|
1057
|
+
return {
|
|
1058
|
+
__REQUENCE_type: REQUENCE_CALLBACK_TAG,
|
|
1059
|
+
lifetime: "durable",
|
|
1060
|
+
name: binding.name,
|
|
1061
|
+
nodeId: ctx.nodeId,
|
|
1062
|
+
bound: binding.bound,
|
|
1063
|
+
outputName: ctx.outputName ?? null,
|
|
1064
|
+
propertyPath: [...path]
|
|
1065
|
+
};
|
|
1066
|
+
}
|
|
1001
1067
|
if (!ctx.onCallback) {
|
|
1002
1068
|
throw new Error(`functions are not serializable on this boundary (no ctx.onCallback) at path "${path.join(".")}"`);
|
|
1003
1069
|
}
|
|
1004
1070
|
return {
|
|
1005
|
-
...ctx.onCallback(callback),
|
|
1071
|
+
...ctx.onCallback(callback, path),
|
|
1072
|
+
lifetime: "connection",
|
|
1006
1073
|
outputName: ctx.outputName ?? null,
|
|
1007
1074
|
propertyPath: [...path],
|
|
1008
|
-
__REQUENCE_type:
|
|
1075
|
+
__REQUENCE_type: REQUENCE_CALLBACK_TAG
|
|
1009
1076
|
};
|
|
1010
1077
|
},
|
|
1011
1078
|
isReference: (value) => isCallbackObject(value),
|
|
@@ -1189,6 +1256,10 @@ function createSurfaceHandlerValueHandler() {
|
|
|
1189
1256
|
tag: SURFACE_HANDLER_TAG,
|
|
1190
1257
|
canHandle: (value) => typeof value === "function",
|
|
1191
1258
|
serialize(handler, ctx, path) {
|
|
1259
|
+
const binding = readDurableCallbackBinding(handler);
|
|
1260
|
+
if (binding) {
|
|
1261
|
+
throw new Error(`durable callback "${binding.name}" was put in a surface's props at "${path.join(".") || "<root>"}" — a callback addresses a position in the node's output schema, so it cannot be a UI prop; write the prop's handler in the UI's defaults instead`);
|
|
1262
|
+
}
|
|
1192
1263
|
return ctx.onSurfaceHandler(handler, path);
|
|
1193
1264
|
},
|
|
1194
1265
|
isReference: (value) => isSurfaceHandlerObject(value),
|
|
@@ -1240,6 +1311,7 @@ function createOutboundBoundary(base) {
|
|
|
1240
1311
|
maxFileSize: base.maxFileSize,
|
|
1241
1312
|
measure,
|
|
1242
1313
|
outputName: opts.outputName ?? null,
|
|
1314
|
+
nodeId: base.nodeId,
|
|
1243
1315
|
onCallback: opts.onCallback,
|
|
1244
1316
|
inlineKeys: opts.inlineKeys,
|
|
1245
1317
|
...opts.bestEffort ? {
|
|
@@ -1292,6 +1364,114 @@ function createInboundBoundary(base = {}) {
|
|
|
1292
1364
|
};
|
|
1293
1365
|
}
|
|
1294
1366
|
|
|
1367
|
+
// src/callbackGrowth.ts
|
|
1368
|
+
var DEV_OVERLAY_FIRST_WARNING = 100;
|
|
1369
|
+
var DEPLOYED_FIRST_WARNING = 1000;
|
|
1370
|
+
var TOP_PATHS = 3;
|
|
1371
|
+
function advance(from, count) {
|
|
1372
|
+
let next = from;
|
|
1373
|
+
while (next <= count) {
|
|
1374
|
+
next *= 10;
|
|
1375
|
+
}
|
|
1376
|
+
return next;
|
|
1377
|
+
}
|
|
1378
|
+
function formatWarning(params) {
|
|
1379
|
+
const worst = [...params.perPath.entries()].sort(([, a], [, b]) => b - a).slice(0, TOP_PATHS).map(([path, count]) => `${path} (${count})`).join(", ");
|
|
1380
|
+
return [
|
|
1381
|
+
`Requence: the functions you yield are piling up in memory and nothing frees them.`,
|
|
1382
|
+
``,
|
|
1383
|
+
`Each one is kept for as long as the task runs, and it holds on to everything it`,
|
|
1384
|
+
`used from the code around it — including the whole value you were handling at`,
|
|
1385
|
+
`the time. On a task that runs for days, this service runs out of memory.`,
|
|
1386
|
+
``,
|
|
1387
|
+
`If a function only needs data, and not a live connection or an open stream,`,
|
|
1388
|
+
`write it once at the top of your file and hand it the data each time:`,
|
|
1389
|
+
``,
|
|
1390
|
+
` const removeItem = createDurableCallback('removeItem', (arg, { id }) => ...)`,
|
|
1391
|
+
``,
|
|
1392
|
+
` yield { remove: removeItem.for({ id: item.id }) }`,
|
|
1393
|
+
``,
|
|
1394
|
+
`Then there is one function, however many times you yield.`,
|
|
1395
|
+
``,
|
|
1396
|
+
` service: ${params.service}`,
|
|
1397
|
+
` task: ${params.taskId}`,
|
|
1398
|
+
` holding: ${params.delivery} from this task, ${params.connection} in this service`,
|
|
1399
|
+
` worst: ${worst}`
|
|
1400
|
+
].join(`
|
|
1401
|
+
`);
|
|
1402
|
+
}
|
|
1403
|
+
function createCallbackGrowthWatch({
|
|
1404
|
+
service,
|
|
1405
|
+
devOverlay,
|
|
1406
|
+
connectionCount,
|
|
1407
|
+
warn
|
|
1408
|
+
}) {
|
|
1409
|
+
const first = devOverlay ? DEV_OVERLAY_FIRST_WARNING : DEPLOYED_FIRST_WARNING;
|
|
1410
|
+
let nextConnection = first;
|
|
1411
|
+
return {
|
|
1412
|
+
forDelivery({ taskId }) {
|
|
1413
|
+
let delivery = 0;
|
|
1414
|
+
let nextDelivery = first;
|
|
1415
|
+
const perPath = new Map;
|
|
1416
|
+
return {
|
|
1417
|
+
record(path) {
|
|
1418
|
+
delivery += 1;
|
|
1419
|
+
const key = formatPath(path);
|
|
1420
|
+
perPath.set(key, (perPath.get(key) ?? 0) + 1);
|
|
1421
|
+
const connection = connectionCount();
|
|
1422
|
+
const crossedDelivery = delivery >= nextDelivery;
|
|
1423
|
+
const crossedConnection = connection >= nextConnection;
|
|
1424
|
+
if (!crossedDelivery && !crossedConnection) {
|
|
1425
|
+
return;
|
|
1426
|
+
}
|
|
1427
|
+
if (crossedDelivery) {
|
|
1428
|
+
nextDelivery = advance(nextDelivery, delivery);
|
|
1429
|
+
}
|
|
1430
|
+
if (crossedConnection) {
|
|
1431
|
+
nextConnection = advance(nextConnection, connection);
|
|
1432
|
+
}
|
|
1433
|
+
warn(formatWarning({ service, taskId, delivery, connection, perPath }));
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
}
|
|
1437
|
+
};
|
|
1438
|
+
}
|
|
1439
|
+
|
|
1440
|
+
// src/durableCallback.ts
|
|
1441
|
+
var RESERVED_CONTEXT_KEY = "configuration";
|
|
1442
|
+
function assertBindable(name, bound) {
|
|
1443
|
+
if (bound === undefined || bound === null) {
|
|
1444
|
+
return;
|
|
1445
|
+
}
|
|
1446
|
+
if (typeof bound !== "object") {
|
|
1447
|
+
throw new Error(`durable callback "${name}" bound a ${typeof bound} — the bound data IS the callback's context, so it has to be an object`);
|
|
1448
|
+
}
|
|
1449
|
+
if (Object.hasOwn(bound, RESERVED_CONTEXT_KEY)) {
|
|
1450
|
+
throw new Error(`durable callback "${name}" bound a "${RESERVED_CONTEXT_KEY}" key — the bound data IS the callback's context, and that name is taken by the node's configuration`);
|
|
1451
|
+
}
|
|
1452
|
+
}
|
|
1453
|
+
var durableCallbacks = new Map;
|
|
1454
|
+
function createDurableCallback(name, handler) {
|
|
1455
|
+
if (durableCallbacks.has(name)) {
|
|
1456
|
+
throw new Error(`two durable callbacks share the name "${name}" — the name is the whole address of a durable callback, so pick a distinct one`);
|
|
1457
|
+
}
|
|
1458
|
+
durableCallbacks.set(name, { handler });
|
|
1459
|
+
const handle = createDurableCallbackReference({ name, bound: undefined });
|
|
1460
|
+
return Object.assign(handle, {
|
|
1461
|
+
for: (bound) => {
|
|
1462
|
+
assertBindable(name, bound);
|
|
1463
|
+
return createDurableCallbackReference({ name, bound });
|
|
1464
|
+
}
|
|
1465
|
+
});
|
|
1466
|
+
}
|
|
1467
|
+
function findDurableCallback(name) {
|
|
1468
|
+
return durableCallbacks.get(name);
|
|
1469
|
+
}
|
|
1470
|
+
function durableCallbackContext(name, bound, configuration) {
|
|
1471
|
+
assertBindable(name, bound);
|
|
1472
|
+
return { ...bound, configuration };
|
|
1473
|
+
}
|
|
1474
|
+
|
|
1295
1475
|
// src/helpers.ts
|
|
1296
1476
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
1297
1477
|
class RetryError extends Error {
|
|
@@ -1488,7 +1668,8 @@ var messageKeySchema = z9.string().transform((str) => deobfuscate(str)).pipe(z9.
|
|
|
1488
1668
|
uploadUrl: arr[2] || undefined,
|
|
1489
1669
|
streamUrl: arr[3] || undefined,
|
|
1490
1670
|
maxPayloadSize: arr[4] && Number.isFinite(Number(arr[4])) ? Number(arr[4]) : undefined,
|
|
1491
|
-
maxFileSize: arr[5] && Number.isFinite(Number(arr[5])) ? Number(arr[5]) : undefined
|
|
1671
|
+
maxFileSize: arr[5] && Number.isFinite(Number(arr[5])) ? Number(arr[5]) : undefined,
|
|
1672
|
+
nodeId: arr[6] || undefined
|
|
1492
1673
|
}));
|
|
1493
1674
|
var headerSchema = z9.object({
|
|
1494
1675
|
properties: z9.object({
|
|
@@ -1509,6 +1690,7 @@ var payloadSchema = z9.object({
|
|
|
1509
1690
|
}).transform((msg) => decodeWireBody(msg.content, msg.properties.contentType)).pipe(z9.object({
|
|
1510
1691
|
input: z9.unknown().optional(),
|
|
1511
1692
|
configuration: z9.unknown().optional(),
|
|
1693
|
+
nodeId: z9.string().optional(),
|
|
1512
1694
|
options: z9.object({
|
|
1513
1695
|
uploadUrl: z9.url().optional(),
|
|
1514
1696
|
streamUrl: z9.url().optional(),
|
|
@@ -1581,6 +1763,15 @@ function safeAck(channel, message) {
|
|
|
1581
1763
|
}
|
|
1582
1764
|
}
|
|
1583
1765
|
}
|
|
1766
|
+
function invocationHeaders(payload, invokingNodeId) {
|
|
1767
|
+
return {
|
|
1768
|
+
...invokingNodeId ? { invokingNodeId } : {},
|
|
1769
|
+
...payload.lifetime === "connection" ? { connectionId: payload.sourceId, callbackId: payload.callbackId } : { callbackName: payload.name, callbackNodeId: payload.nodeId }
|
|
1770
|
+
};
|
|
1771
|
+
}
|
|
1772
|
+
function invocationPayload(payload, arg) {
|
|
1773
|
+
return payload.lifetime === "connection" ? arg : { arg, bound: payload.bound };
|
|
1774
|
+
}
|
|
1584
1775
|
function safeNack(channel, message) {
|
|
1585
1776
|
try {
|
|
1586
1777
|
channel.nack(message);
|
|
@@ -1615,7 +1806,7 @@ function createConnection({
|
|
|
1615
1806
|
clientProperties: {
|
|
1616
1807
|
...connectionOptions?.clientProperties,
|
|
1617
1808
|
...buildServiceClientProperties({
|
|
1618
|
-
libVersion: "javascript@0.8.2-edge.
|
|
1809
|
+
libVersion: "javascript@0.8.2-edge.1157",
|
|
1619
1810
|
serviceVersion: version,
|
|
1620
1811
|
name,
|
|
1621
1812
|
devOverlay: Boolean(devOverlay)
|
|
@@ -1670,6 +1861,12 @@ function createConnection({
|
|
|
1670
1861
|
const sentComponents = new Set;
|
|
1671
1862
|
const generatorTerminators = new Map;
|
|
1672
1863
|
const callbacks = new Map;
|
|
1864
|
+
const callbackGrowth = createCallbackGrowthWatch({
|
|
1865
|
+
service: baseQueue,
|
|
1866
|
+
devOverlay: Boolean(devOverlay),
|
|
1867
|
+
connectionCount: () => callbacks.size,
|
|
1868
|
+
warn: (text) => simple_default.warn(text)
|
|
1869
|
+
});
|
|
1673
1870
|
const backchannelInbound = createInboundBoundary(passthroughByteReferences ? { transformer: passthroughInboundTransformer } : {});
|
|
1674
1871
|
const channelWrapper = connection.createChannel({
|
|
1675
1872
|
async setup(channel) {
|
|
@@ -1824,6 +2021,43 @@ function createConnection({
|
|
|
1824
2021
|
});
|
|
1825
2022
|
}
|
|
1826
2023
|
});
|
|
2024
|
+
async function runDurableCallbackInvocation(payload) {
|
|
2025
|
+
const parsed = durableCallbackInvocationSchema.safeParse(payload);
|
|
2026
|
+
if (!parsed.success) {
|
|
2027
|
+
simple_default.error("Requence: dropped a malformed durable callback invocation — it does not name a callback this build can run");
|
|
2028
|
+
return;
|
|
2029
|
+
}
|
|
2030
|
+
const { name: name2, bound, arg, configuration, taskId, nodeId } = parsed.data;
|
|
2031
|
+
const registration = findDurableCallback(name2);
|
|
2032
|
+
if (!registration) {
|
|
2033
|
+
throw new Error(`no durable callback registered as "${name2}" — a reference naming it was emitted by node ${nodeId} of task ${taskId}, and this version declares none`);
|
|
2034
|
+
}
|
|
2035
|
+
await registration.handler(arg, durableCallbackContext(name2, bound, configuration));
|
|
2036
|
+
}
|
|
2037
|
+
const callbackQueue = serviceCallbackQueueName(queue);
|
|
2038
|
+
const callbackChannelWrapper = connection.createChannel({
|
|
2039
|
+
async setup(channel) {
|
|
2040
|
+
await channel.assertQueue(callbackQueue, DURABLE_CALLBACK_QUEUE_ARGUMENTS);
|
|
2041
|
+
await channel.bindQueue(callbackQueue, "service", callbackQueue);
|
|
2042
|
+
await channel.prefetch(prefetch);
|
|
2043
|
+
await channel.consume(callbackQueue, async (message) => {
|
|
2044
|
+
if (!message) {
|
|
2045
|
+
return;
|
|
2046
|
+
}
|
|
2047
|
+
try {
|
|
2048
|
+
await runDurableCallbackInvocation(JSON.parse(message.content.toString()));
|
|
2049
|
+
} catch (error) {
|
|
2050
|
+
simple_default.error("Requence: durable callback threw:", error instanceof Error ? error.stack ?? error.message : error);
|
|
2051
|
+
}
|
|
2052
|
+
safeAck(channel, message);
|
|
2053
|
+
});
|
|
2054
|
+
}
|
|
2055
|
+
});
|
|
2056
|
+
callbackChannelWrapper.on("error", (err) => {
|
|
2057
|
+
if (!silent) {
|
|
2058
|
+
simple_default.error("Requence AMQP callback channel error:", err.message);
|
|
2059
|
+
}
|
|
2060
|
+
});
|
|
1827
2061
|
handlerChannelWrapper.on("error", (err) => {
|
|
1828
2062
|
if (!silent) {
|
|
1829
2063
|
simple_default.error("Requence AMQP handler channel error:", err.message);
|
|
@@ -1917,7 +2151,7 @@ function createConnection({
|
|
|
1917
2151
|
if (layer !== "props") {
|
|
1918
2152
|
throw new Error(`a function in a render payload is only a handler under props or defaults (found at "${payloadPath.join(".")}")`);
|
|
1919
2153
|
}
|
|
1920
|
-
const { sourceId, callbackId } = deps.registerCallback(handler);
|
|
2154
|
+
const { sourceId, callbackId } = deps.registerCallback(handler, payloadPath);
|
|
1921
2155
|
return {
|
|
1922
2156
|
__REQUENCE_type: SURFACE_HANDLER_TAG,
|
|
1923
2157
|
lifetime: "connection",
|
|
@@ -2001,13 +2235,15 @@ function createConnection({
|
|
|
2001
2235
|
};
|
|
2002
2236
|
const payload = payloadSchema.parse(message);
|
|
2003
2237
|
const abortController = new AbortController;
|
|
2004
|
-
const
|
|
2238
|
+
const growth = callbackGrowth.forDelivery({ taskId });
|
|
2239
|
+
const registerCallback = (callback, path2) => {
|
|
2005
2240
|
const callbackId = crypto.randomUUID();
|
|
2006
2241
|
registeredCallbackIds.add(callbackId);
|
|
2007
2242
|
callbacks.set(callbackId, {
|
|
2008
2243
|
callback,
|
|
2009
2244
|
onCallbackInvoke: dispatchInvocation
|
|
2010
2245
|
});
|
|
2246
|
+
growth.record(path2);
|
|
2011
2247
|
return { sourceId: connectionId, callbackId };
|
|
2012
2248
|
};
|
|
2013
2249
|
const outbound = createOutboundBoundary({
|
|
@@ -2015,24 +2251,24 @@ function createConnection({
|
|
|
2015
2251
|
streamUrl: payload.options.streamUrl,
|
|
2016
2252
|
maxPayloadSize: payload.options.maxPayloadSize,
|
|
2017
2253
|
maxFileSize: payload.options.maxFileSize,
|
|
2254
|
+
nodeId: payload.nodeId,
|
|
2018
2255
|
wireCodec: dispatchCodec,
|
|
2019
2256
|
signal: abortController.signal,
|
|
2020
2257
|
warn: (msg, error) => simple_default.warn(`${msg} (task ${taskId})`, error instanceof Error ? error.message : error ?? "")
|
|
2021
2258
|
});
|
|
2022
|
-
const dispatchInvocation = (
|
|
2023
|
-
outbound.track(outbound.send(
|
|
2024
|
-
outputName:
|
|
2259
|
+
const dispatchInvocation = (invocation) => {
|
|
2260
|
+
outbound.track(outbound.send(invocation.arg, {
|
|
2261
|
+
outputName: invocation.outputName,
|
|
2025
2262
|
onCallback: registerCallback
|
|
2026
2263
|
}).then((data) => publish({
|
|
2027
2264
|
index: 0,
|
|
2028
2265
|
version,
|
|
2029
2266
|
taskId,
|
|
2030
2267
|
messageId,
|
|
2031
|
-
data,
|
|
2032
|
-
outputName:
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
propertyPath: params.propertyPath,
|
|
2268
|
+
data: invocationPayload(invocation, data),
|
|
2269
|
+
outputName: invocation.outputName,
|
|
2270
|
+
propertyPath: invocation.propertyPath,
|
|
2271
|
+
...invocationHeaders(invocation, payload.nodeId),
|
|
2036
2272
|
epoch
|
|
2037
2273
|
})));
|
|
2038
2274
|
};
|
|
@@ -2059,13 +2295,7 @@ function createConnection({
|
|
|
2059
2295
|
passthroughByteReferences,
|
|
2060
2296
|
sends: {
|
|
2061
2297
|
...buildSendApi(publishDeps),
|
|
2062
|
-
invokeCallback: (ref, arg) => dispatchInvocation({
|
|
2063
|
-
sourceId: ref.sourceId,
|
|
2064
|
-
callbackId: ref.callbackId,
|
|
2065
|
-
outputName: ref.outputName,
|
|
2066
|
-
propertyPath: ref.propertyPath,
|
|
2067
|
-
arg
|
|
2068
|
-
}),
|
|
2298
|
+
invokeCallback: (ref, arg) => dispatchInvocation({ ...ref, arg }),
|
|
2069
2299
|
options: payload.options
|
|
2070
2300
|
},
|
|
2071
2301
|
onLog(debugMethod, data) {
|
|
@@ -2090,7 +2320,7 @@ function createConnection({
|
|
|
2090
2320
|
onDefer(reason) {
|
|
2091
2321
|
deferred = true;
|
|
2092
2322
|
deferredReason = reason || null;
|
|
2093
|
-
return obfuscate(taskId, messageId, payload.options.uploadUrl ?? "", payload.options.streamUrl ?? "", payload.options.maxPayloadSize?.toString() ?? "", payload.options.maxFileSize?.toString() ?? "");
|
|
2323
|
+
return obfuscate(taskId, messageId, payload.options.uploadUrl ?? "", payload.options.streamUrl ?? "", payload.options.maxPayloadSize?.toString() ?? "", payload.options.maxFileSize?.toString() ?? "", payload.nodeId ?? "");
|
|
2094
2324
|
},
|
|
2095
2325
|
onCallback: dispatchInvocation
|
|
2096
2326
|
});
|
|
@@ -2103,7 +2333,7 @@ function createConnection({
|
|
|
2103
2333
|
begin: true,
|
|
2104
2334
|
epoch,
|
|
2105
2335
|
...buildServiceIdentityHeaders({
|
|
2106
|
-
libVersion: "javascript@0.8.2-edge.
|
|
2336
|
+
libVersion: "javascript@0.8.2-edge.1157",
|
|
2107
2337
|
name
|
|
2108
2338
|
})
|
|
2109
2339
|
});
|
|
@@ -2327,6 +2557,7 @@ function createConnection({
|
|
|
2327
2557
|
const api = {
|
|
2328
2558
|
close: async () => {
|
|
2329
2559
|
stopUIWatch?.();
|
|
2560
|
+
await callbackChannelWrapper.close();
|
|
2330
2561
|
await handlerChannelWrapper.close();
|
|
2331
2562
|
await channelWrapper.close();
|
|
2332
2563
|
await connection.close();
|
|
@@ -2346,29 +2577,30 @@ function createConnection({
|
|
|
2346
2577
|
};
|
|
2347
2578
|
const registeredCallbackIds = new Set;
|
|
2348
2579
|
const outbound = createOutboundBoundary(options);
|
|
2349
|
-
const
|
|
2580
|
+
const growth = callbackGrowth.forDelivery({ taskId });
|
|
2581
|
+
const registerCallback = (callback, path2) => {
|
|
2350
2582
|
const callbackId = crypto.randomUUID();
|
|
2351
2583
|
registeredCallbackIds.add(callbackId);
|
|
2352
2584
|
callbacks.set(callbackId, {
|
|
2353
2585
|
callback,
|
|
2354
2586
|
onCallbackInvoke: dispatchInvocation
|
|
2355
2587
|
});
|
|
2588
|
+
growth.record(path2);
|
|
2356
2589
|
return { sourceId: connectionId, callbackId };
|
|
2357
2590
|
};
|
|
2358
|
-
const dispatchInvocation = (
|
|
2359
|
-
outbound.track(outbound.send(
|
|
2360
|
-
outputName:
|
|
2591
|
+
const dispatchInvocation = (invocation) => {
|
|
2592
|
+
outbound.track(outbound.send(invocation.arg, {
|
|
2593
|
+
outputName: invocation.outputName,
|
|
2361
2594
|
onCallback: registerCallback
|
|
2362
2595
|
}).then((data) => publish({
|
|
2363
2596
|
index: 0,
|
|
2364
2597
|
version,
|
|
2365
2598
|
taskId,
|
|
2366
2599
|
messageId,
|
|
2367
|
-
data,
|
|
2368
|
-
outputName:
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
propertyPath: params.propertyPath
|
|
2600
|
+
data: invocationPayload(invocation, data),
|
|
2601
|
+
outputName: invocation.outputName,
|
|
2602
|
+
propertyPath: invocation.propertyPath,
|
|
2603
|
+
...invocationHeaders(invocation, options.nodeId)
|
|
2372
2604
|
})));
|
|
2373
2605
|
};
|
|
2374
2606
|
const publishDeps = {
|
|
@@ -2517,30 +2749,36 @@ function asyncEventEmitter(initial = []) {
|
|
|
2517
2749
|
context?.terminated.then(() => {
|
|
2518
2750
|
terminated = true;
|
|
2519
2751
|
});
|
|
2520
|
-
|
|
2521
|
-
|
|
2752
|
+
const queue = structuredClone(initial);
|
|
2753
|
+
let waiting = null;
|
|
2522
2754
|
return {
|
|
2523
2755
|
push: (value) => {
|
|
2524
|
-
if (
|
|
2756
|
+
if (waiting) {
|
|
2757
|
+
const resolve2 = waiting;
|
|
2758
|
+
waiting = null;
|
|
2525
2759
|
resolve2(value);
|
|
2526
|
-
|
|
2527
|
-
initialValues.push(value);
|
|
2760
|
+
return;
|
|
2528
2761
|
}
|
|
2762
|
+
queue.push(value);
|
|
2529
2763
|
},
|
|
2530
2764
|
[Symbol.asyncIterator]() {
|
|
2531
2765
|
return {
|
|
2532
2766
|
async next() {
|
|
2533
|
-
if (
|
|
2534
|
-
return { value:
|
|
2767
|
+
if (queue.length > 0) {
|
|
2768
|
+
return { value: queue.shift(), done: false };
|
|
2535
2769
|
}
|
|
2536
2770
|
const defer = Promise.withResolvers();
|
|
2537
|
-
|
|
2771
|
+
waiting = defer.resolve;
|
|
2538
2772
|
if (context) {
|
|
2539
2773
|
const value = await Promise.race([
|
|
2540
2774
|
defer.promise,
|
|
2541
2775
|
context.terminated
|
|
2542
2776
|
]);
|
|
2543
|
-
|
|
2777
|
+
if (terminated) {
|
|
2778
|
+
waiting = null;
|
|
2779
|
+
return { done: true, value: undefined };
|
|
2780
|
+
}
|
|
2781
|
+
return { done: false, value };
|
|
2544
2782
|
}
|
|
2545
2783
|
return { value: await defer.promise, done: false };
|
|
2546
2784
|
}
|
|
@@ -2643,6 +2881,7 @@ export {
|
|
|
2643
2881
|
isUnreachableStatus,
|
|
2644
2882
|
createUI,
|
|
2645
2883
|
createService,
|
|
2884
|
+
createDurableCallback,
|
|
2646
2885
|
createCallback,
|
|
2647
2886
|
asyncEventEmitter,
|
|
2648
2887
|
assertReachable,
|
|
@@ -2655,5 +2894,5 @@ export {
|
|
|
2655
2894
|
PayloadTooLargeError
|
|
2656
2895
|
};
|
|
2657
2896
|
|
|
2658
|
-
//# debugId=
|
|
2897
|
+
//# debugId=B9ACB95FA979832B64756E2164756E21
|
|
2659
2898
|
//# sourceMappingURL=index.js.map
|