rivetkit 2.0.24-rc.1 → 2.0.25-rc.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/dist/schemas/actor-persist/v1.ts +6 -0
- package/dist/schemas/actor-persist/v2.ts +9 -3
- package/dist/schemas/actor-persist/v3.ts +280 -0
- package/dist/schemas/client-protocol/v1.ts +6 -0
- package/dist/schemas/client-protocol/v2.ts +438 -0
- package/dist/schemas/file-system-driver/v1.ts +6 -0
- package/dist/schemas/file-system-driver/v2.ts +142 -0
- package/dist/tsup/actor/errors.cjs +2 -4
- package/dist/tsup/actor/errors.cjs.map +1 -1
- package/dist/tsup/actor/errors.d.cts +7 -10
- package/dist/tsup/actor/errors.d.ts +7 -10
- package/dist/tsup/actor/errors.js +9 -11
- package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.cts → actor-router-consts-DzI2szci.d.cts} +5 -9
- package/dist/tsup/{actor-router-consts-B3Lu87yJ.d.ts → actor-router-consts-DzI2szci.d.ts} +5 -9
- package/dist/tsup/{chunk-ZTH3KYFH.cjs → chunk-3FG5OJ3G.cjs} +3 -3
- package/dist/tsup/{chunk-ZTH3KYFH.cjs.map → chunk-3FG5OJ3G.cjs.map} +1 -1
- package/dist/tsup/{chunk-BLK27ES3.js → chunk-6JN6W6G3.js} +44 -56
- package/dist/tsup/chunk-6JN6W6G3.js.map +1 -0
- package/dist/tsup/chunk-7IBNNGQ2.js +514 -0
- package/dist/tsup/chunk-7IBNNGQ2.js.map +1 -0
- package/dist/tsup/{chunk-36JJ4IQB.cjs → chunk-AZATXPR4.cjs} +4 -8
- package/dist/tsup/chunk-AZATXPR4.cjs.map +1 -0
- package/dist/tsup/chunk-B7MENRD5.cjs +5694 -0
- package/dist/tsup/chunk-B7MENRD5.cjs.map +1 -0
- package/dist/tsup/{chunk-BOMZS2TJ.js → chunk-BBVFDEYD.js} +9 -9
- package/dist/tsup/chunk-BBVFDEYD.js.map +1 -0
- package/dist/tsup/{chunk-KSRXX3Z4.cjs → chunk-D6762AOA.cjs} +20 -25
- package/dist/tsup/chunk-D6762AOA.cjs.map +1 -0
- package/dist/tsup/{chunk-2JYPS5YM.cjs → chunk-E63WZNMR.cjs} +6 -6
- package/dist/tsup/chunk-E63WZNMR.cjs.map +1 -0
- package/dist/tsup/{chunk-YBG6R7LX.js → chunk-EDGN4OC7.js} +3 -7
- package/dist/tsup/chunk-EDGN4OC7.js.map +1 -0
- package/dist/tsup/{chunk-BYMKMOBS.js → chunk-FLOQ3UWM.js} +1844 -1681
- package/dist/tsup/chunk-FLOQ3UWM.js.map +1 -0
- package/dist/tsup/{chunk-7L65NNWP.cjs → chunk-H7GV5DIW.cjs} +187 -185
- package/dist/tsup/chunk-H7GV5DIW.cjs.map +1 -0
- package/dist/tsup/{chunk-227FEWMB.js → chunk-HZYZ7JSF.js} +3322 -2251
- package/dist/tsup/chunk-HZYZ7JSF.js.map +1 -0
- package/dist/tsup/{chunk-FX7TWFQR.js → chunk-IDJK7ILQ.js} +2 -6
- package/dist/tsup/chunk-IDJK7ILQ.js.map +1 -0
- package/dist/tsup/{chunk-VHGY7PU5.cjs → chunk-ILFXA4AL.cjs} +1900 -1737
- package/dist/tsup/chunk-ILFXA4AL.cjs.map +1 -0
- package/dist/tsup/chunk-MV6M3FDL.cjs +514 -0
- package/dist/tsup/chunk-MV6M3FDL.cjs.map +1 -0
- package/dist/tsup/{chunk-PLUN2NQT.js → chunk-NWBKMCWC.js} +189 -187
- package/dist/tsup/chunk-NWBKMCWC.js.map +1 -0
- package/dist/tsup/{chunk-CD33GT6Z.js → chunk-QIHBDXTO.js} +2 -2
- package/dist/tsup/{chunk-G64QUEDJ.js → chunk-W6RDS6NW.js} +23 -28
- package/dist/tsup/chunk-W6RDS6NW.js.map +1 -0
- package/dist/tsup/{chunk-INNFK746.cjs → chunk-WQU4M4ZC.cjs} +10 -14
- package/dist/tsup/chunk-WQU4M4ZC.cjs.map +1 -0
- package/dist/tsup/{chunk-SHVX2QUR.cjs → chunk-XKZA47XS.cjs} +17 -17
- package/dist/tsup/chunk-XKZA47XS.cjs.map +1 -0
- package/dist/tsup/{chunk-HHFKKVLR.cjs → chunk-YHWIOWVA.cjs} +45 -57
- package/dist/tsup/chunk-YHWIOWVA.cjs.map +1 -0
- package/dist/tsup/{chunk-YBHYXIP6.js → chunk-YVL6IRUM.js} +3 -3
- package/dist/tsup/chunk-YVL6IRUM.js.map +1 -0
- package/dist/tsup/client/mod.cjs +9 -9
- package/dist/tsup/client/mod.d.cts +5 -7
- package/dist/tsup/client/mod.d.ts +5 -7
- package/dist/tsup/client/mod.js +8 -8
- package/dist/tsup/common/log.cjs +3 -3
- package/dist/tsup/common/log.js +2 -2
- package/dist/tsup/common/websocket.cjs +4 -4
- package/dist/tsup/common/websocket.js +3 -3
- package/dist/tsup/{conn-B3Vhbgnd.d.ts → config-BRDYDraU.d.cts} +1119 -1047
- package/dist/tsup/{conn-DJWL3nGx.d.cts → config-Bo-blHpJ.d.ts} +1119 -1047
- package/dist/tsup/driver-helpers/mod.cjs +5 -13
- package/dist/tsup/driver-helpers/mod.cjs.map +1 -1
- package/dist/tsup/driver-helpers/mod.d.cts +11 -9
- package/dist/tsup/driver-helpers/mod.d.ts +11 -9
- package/dist/tsup/driver-helpers/mod.js +14 -22
- package/dist/tsup/driver-test-suite/mod.cjs +474 -303
- package/dist/tsup/driver-test-suite/mod.cjs.map +1 -1
- package/dist/tsup/driver-test-suite/mod.d.cts +6 -9
- package/dist/tsup/driver-test-suite/mod.d.ts +6 -9
- package/dist/tsup/driver-test-suite/mod.js +1085 -914
- package/dist/tsup/driver-test-suite/mod.js.map +1 -1
- package/dist/tsup/inspector/mod.cjs +6 -6
- package/dist/tsup/inspector/mod.d.cts +5 -7
- package/dist/tsup/inspector/mod.d.ts +5 -7
- package/dist/tsup/inspector/mod.js +5 -5
- package/dist/tsup/mod.cjs +10 -16
- package/dist/tsup/mod.cjs.map +1 -1
- package/dist/tsup/mod.d.cts +23 -25
- package/dist/tsup/mod.d.ts +23 -25
- package/dist/tsup/mod.js +17 -23
- package/dist/tsup/test/mod.cjs +11 -11
- package/dist/tsup/test/mod.d.cts +4 -6
- package/dist/tsup/test/mod.d.ts +4 -6
- package/dist/tsup/test/mod.js +10 -10
- package/dist/tsup/utils.cjs +3 -5
- package/dist/tsup/utils.cjs.map +1 -1
- package/dist/tsup/utils.d.cts +1 -2
- package/dist/tsup/utils.d.ts +1 -2
- package/dist/tsup/utils.js +2 -4
- package/package.json +13 -6
- package/src/actor/config.ts +56 -44
- package/src/actor/conn/driver.ts +61 -0
- package/src/actor/conn/drivers/http.ts +17 -0
- package/src/actor/conn/drivers/raw-request.ts +24 -0
- package/src/actor/conn/drivers/raw-websocket.ts +65 -0
- package/src/actor/conn/drivers/websocket.ts +129 -0
- package/src/actor/conn/mod.ts +232 -0
- package/src/actor/conn/persisted.ts +81 -0
- package/src/actor/conn/state-manager.ts +196 -0
- package/src/actor/contexts/action.ts +23 -0
- package/src/actor/{context.ts → contexts/actor.ts} +19 -8
- package/src/actor/contexts/conn-init.ts +31 -0
- package/src/actor/contexts/conn.ts +48 -0
- package/src/actor/contexts/create-conn-state.ts +13 -0
- package/src/actor/contexts/on-before-connect.ts +13 -0
- package/src/actor/contexts/on-connect.ts +22 -0
- package/src/actor/contexts/request.ts +48 -0
- package/src/actor/contexts/websocket.ts +48 -0
- package/src/actor/definition.ts +3 -3
- package/src/actor/driver.ts +36 -5
- package/src/actor/errors.ts +19 -24
- package/src/actor/instance/connection-manager.ts +465 -0
- package/src/actor/instance/event-manager.ts +292 -0
- package/src/actor/instance/kv.ts +15 -0
- package/src/actor/instance/mod.ts +1107 -0
- package/src/actor/instance/persisted.ts +67 -0
- package/src/actor/instance/schedule-manager.ts +349 -0
- package/src/actor/instance/state-manager.ts +502 -0
- package/src/actor/mod.ts +13 -16
- package/src/actor/protocol/old.ts +131 -43
- package/src/actor/protocol/serde.ts +19 -4
- package/src/actor/router-endpoints.ts +61 -586
- package/src/actor/router-websocket-endpoints.ts +408 -0
- package/src/actor/router.ts +63 -197
- package/src/actor/schedule.ts +1 -1
- package/src/client/actor-conn.ts +183 -249
- package/src/client/actor-handle.ts +29 -6
- package/src/client/client.ts +0 -4
- package/src/client/config.ts +1 -4
- package/src/client/mod.ts +0 -1
- package/src/client/raw-utils.ts +3 -3
- package/src/client/utils.ts +85 -39
- package/src/common/actor-router-consts.ts +5 -12
- package/src/common/{inline-websocket-adapter2.ts → inline-websocket-adapter.ts} +26 -48
- package/src/common/log.ts +1 -1
- package/src/common/router.ts +28 -17
- package/src/common/utils.ts +2 -0
- package/src/driver-helpers/mod.ts +7 -10
- package/src/driver-helpers/utils.ts +18 -9
- package/src/driver-test-suite/mod.ts +26 -50
- package/src/driver-test-suite/test-inline-client-driver.ts +27 -51
- package/src/driver-test-suite/tests/actor-conn-hibernation.ts +150 -0
- package/src/driver-test-suite/tests/actor-conn-state.ts +1 -4
- package/src/driver-test-suite/tests/actor-conn.ts +5 -9
- package/src/driver-test-suite/tests/actor-destroy.ts +294 -0
- package/src/driver-test-suite/tests/actor-driver.ts +0 -7
- package/src/driver-test-suite/tests/actor-handle.ts +12 -12
- package/src/driver-test-suite/tests/actor-metadata.ts +1 -1
- package/src/driver-test-suite/tests/manager-driver.ts +1 -1
- package/src/driver-test-suite/tests/raw-http-direct-registry.ts +8 -8
- package/src/driver-test-suite/tests/raw-http-request-properties.ts +6 -5
- package/src/driver-test-suite/tests/raw-http.ts +5 -5
- package/src/driver-test-suite/tests/raw-websocket-direct-registry.ts +7 -7
- package/src/driver-test-suite/tests/request-access.ts +4 -4
- package/src/driver-test-suite/utils.ts +6 -10
- package/src/drivers/engine/actor-driver.ts +614 -424
- package/src/drivers/engine/mod.ts +0 -1
- package/src/drivers/file-system/actor.ts +24 -12
- package/src/drivers/file-system/global-state.ts +427 -37
- package/src/drivers/file-system/manager.ts +71 -83
- package/src/drivers/file-system/mod.ts +3 -0
- package/src/drivers/file-system/utils.ts +18 -8
- package/src/engine-process/mod.ts +38 -38
- package/src/inspector/utils.ts +7 -5
- package/src/manager/driver.ts +11 -4
- package/src/manager/gateway.ts +4 -29
- package/src/manager/protocol/mod.ts +0 -2
- package/src/manager/protocol/query.ts +0 -4
- package/src/manager/router.ts +67 -64
- package/src/manager-api/actors.ts +13 -0
- package/src/mod.ts +1 -3
- package/src/registry/mod.ts +20 -20
- package/src/registry/serve.ts +9 -14
- package/src/remote-manager-driver/actor-websocket-client.ts +1 -16
- package/src/remote-manager-driver/api-endpoints.ts +13 -1
- package/src/remote-manager-driver/api-utils.ts +8 -0
- package/src/remote-manager-driver/metadata.ts +58 -0
- package/src/remote-manager-driver/mod.ts +47 -62
- package/src/remote-manager-driver/ws-proxy.ts +1 -1
- package/src/schemas/actor-persist/mod.ts +1 -1
- package/src/schemas/actor-persist/versioned.ts +56 -31
- package/src/schemas/client-protocol/mod.ts +1 -1
- package/src/schemas/client-protocol/versioned.ts +41 -21
- package/src/schemas/client-protocol-zod/mod.ts +103 -0
- package/src/schemas/file-system-driver/mod.ts +1 -1
- package/src/schemas/file-system-driver/versioned.ts +42 -19
- package/src/serde.ts +33 -11
- package/src/test/mod.ts +7 -3
- package/src/utils/node.ts +173 -0
- package/src/utils.ts +0 -4
- package/dist/tsup/chunk-227FEWMB.js.map +0 -1
- package/dist/tsup/chunk-2JYPS5YM.cjs.map +0 -1
- package/dist/tsup/chunk-36JJ4IQB.cjs.map +0 -1
- package/dist/tsup/chunk-7L65NNWP.cjs.map +0 -1
- package/dist/tsup/chunk-BLK27ES3.js.map +0 -1
- package/dist/tsup/chunk-BOMZS2TJ.js.map +0 -1
- package/dist/tsup/chunk-BYMKMOBS.js.map +0 -1
- package/dist/tsup/chunk-FX7TWFQR.js.map +0 -1
- package/dist/tsup/chunk-G64QUEDJ.js.map +0 -1
- package/dist/tsup/chunk-HHFKKVLR.cjs.map +0 -1
- package/dist/tsup/chunk-INNFK746.cjs.map +0 -1
- package/dist/tsup/chunk-KSRXX3Z4.cjs.map +0 -1
- package/dist/tsup/chunk-O44LFKSB.cjs +0 -4623
- package/dist/tsup/chunk-O44LFKSB.cjs.map +0 -1
- package/dist/tsup/chunk-PLUN2NQT.js.map +0 -1
- package/dist/tsup/chunk-S4UJG7ZE.js +0 -1119
- package/dist/tsup/chunk-S4UJG7ZE.js.map +0 -1
- package/dist/tsup/chunk-SHVX2QUR.cjs.map +0 -1
- package/dist/tsup/chunk-VFB23BYZ.cjs +0 -1119
- package/dist/tsup/chunk-VFB23BYZ.cjs.map +0 -1
- package/dist/tsup/chunk-VHGY7PU5.cjs.map +0 -1
- package/dist/tsup/chunk-YBG6R7LX.js.map +0 -1
- package/dist/tsup/chunk-YBHYXIP6.js.map +0 -1
- package/src/actor/action.ts +0 -178
- package/src/actor/conn-drivers.ts +0 -216
- package/src/actor/conn-socket.ts +0 -8
- package/src/actor/conn.ts +0 -272
- package/src/actor/instance.ts +0 -2336
- package/src/actor/persisted.ts +0 -49
- package/src/actor/unstable-react.ts +0 -110
- package/src/driver-test-suite/tests/actor-reconnect.ts +0 -170
- package/src/drivers/engine/kv.ts +0 -3
- package/src/manager/hono-websocket-adapter.ts +0 -393
- /package/dist/tsup/{chunk-CD33GT6Z.js.map → chunk-QIHBDXTO.js.map} +0 -0
|
@@ -4,6 +4,7 @@ import invariant from "invariant";
|
|
|
4
4
|
import { deserializeActorKey, serializeActorKey } from "@/actor/keys";
|
|
5
5
|
import { generateRandomString } from "@/actor/utils";
|
|
6
6
|
import type { ClientConfig } from "@/client/client";
|
|
7
|
+
import type { MetadataResponse } from "@/common/router";
|
|
7
8
|
import { noopNext, stringifyError } from "@/common/utils";
|
|
8
9
|
import type {
|
|
9
10
|
ActorOutput,
|
|
@@ -11,6 +12,7 @@ import type {
|
|
|
11
12
|
GetForIdInput,
|
|
12
13
|
GetOrCreateWithKeyInput,
|
|
13
14
|
GetWithKeyInput,
|
|
15
|
+
ListActorsInput,
|
|
14
16
|
ManagerDisplayInformation,
|
|
15
17
|
ManagerDriver,
|
|
16
18
|
} from "@/driver-helpers/mod";
|
|
@@ -29,9 +31,11 @@ import {
|
|
|
29
31
|
getActorByKey,
|
|
30
32
|
getMetadata,
|
|
31
33
|
getOrCreateActor,
|
|
34
|
+
listActorsByName,
|
|
32
35
|
} from "./api-endpoints";
|
|
33
36
|
import { EngineApiError, getEndpoint } from "./api-utils";
|
|
34
37
|
import { logger } from "./log";
|
|
38
|
+
import { lookupMetadataCached } from "./metadata";
|
|
35
39
|
import { createWebSocketProxy } from "./ws-proxy";
|
|
36
40
|
|
|
37
41
|
// TODO:
|
|
@@ -48,9 +52,6 @@ import { createWebSocketProxy } from "./ws-proxy";
|
|
|
48
52
|
// };
|
|
49
53
|
// })();
|
|
50
54
|
|
|
51
|
-
// Global cache to store metadata check promises for each endpoint
|
|
52
|
-
const metadataCheckCache = new Map<string, Promise<void>>();
|
|
53
|
-
|
|
54
55
|
export class RemoteManagerDriver implements ManagerDriver {
|
|
55
56
|
#config: ClientConfig;
|
|
56
57
|
#metadataPromise: Promise<void> | undefined;
|
|
@@ -63,64 +64,38 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
63
64
|
logger().info(
|
|
64
65
|
"detected next.js build phase, disabling health check",
|
|
65
66
|
);
|
|
66
|
-
runConfig.
|
|
67
|
+
runConfig.disableMetadataLookup = true;
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
|
|
70
|
+
// Clone config so we can mutate the endpoint in #metadataPromise
|
|
71
|
+
// NOTE: This is a shallow clone, so mutating nested properties will not do anything
|
|
72
|
+
this.#config = { ...runConfig };
|
|
70
73
|
|
|
71
74
|
// Perform metadata check if enabled
|
|
72
|
-
if (!runConfig.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
75
|
+
if (!runConfig.disableMetadataLookup) {
|
|
76
|
+
// This should never error, since it uses pRetry. If it does for
|
|
77
|
+
// any reason, we'll surface the error anywhere #metadataPromise is
|
|
78
|
+
// awaited.
|
|
79
|
+
this.#metadataPromise = lookupMetadataCached(this.#config).then(
|
|
80
|
+
(metadataData) => {
|
|
81
|
+
// Override endpoint for all future requests
|
|
82
|
+
if (metadataData.clientEndpoint) {
|
|
83
|
+
this.#config.endpoint = metadataData.clientEndpoint;
|
|
84
|
+
logger().info({
|
|
85
|
+
msg: "overriding cached client endpoint",
|
|
86
|
+
endpoint: metadataData.clientEndpoint,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
86
89
|
|
|
87
|
-
// Check if metadata check is already in progress or completed for this endpoint
|
|
88
|
-
const existingPromise = metadataCheckCache.get(endpoint);
|
|
89
|
-
if (existingPromise) {
|
|
90
|
-
return existingPromise;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
// Create and store the promise immediately to prevent racing requests
|
|
94
|
-
const metadataCheckPromise = (async () => {
|
|
95
|
-
try {
|
|
96
|
-
const metadataData = await getMetadata(config);
|
|
97
|
-
|
|
98
|
-
if (metadataData.clientEndpoint) {
|
|
99
90
|
logger().info({
|
|
100
|
-
msg: "
|
|
101
|
-
|
|
91
|
+
msg: "connected to rivetkit manager",
|
|
92
|
+
runtime: metadataData.runtime,
|
|
93
|
+
version: metadataData.version,
|
|
94
|
+
runner: metadataData.runner,
|
|
102
95
|
});
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
// Log successful metadata check with runtime and version info
|
|
107
|
-
logger().info({
|
|
108
|
-
msg: "connected to rivetkit manager",
|
|
109
|
-
runtime: metadataData.runtime,
|
|
110
|
-
version: metadataData.version,
|
|
111
|
-
runner: metadataData.runner,
|
|
112
|
-
});
|
|
113
|
-
} catch (error) {
|
|
114
|
-
logger().error({
|
|
115
|
-
msg: "health check failed, validate the Rivet endpoint is configured correctly",
|
|
116
|
-
endpoint,
|
|
117
|
-
error: stringifyError(error),
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
})();
|
|
121
|
-
|
|
122
|
-
metadataCheckCache.set(endpoint, metadataCheckPromise);
|
|
123
|
-
return metadataCheckPromise;
|
|
96
|
+
},
|
|
97
|
+
);
|
|
98
|
+
}
|
|
124
99
|
}
|
|
125
100
|
|
|
126
101
|
async getForId({
|
|
@@ -282,6 +257,24 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
282
257
|
};
|
|
283
258
|
}
|
|
284
259
|
|
|
260
|
+
async listActors({ c, name }: ListActorsInput): Promise<ActorOutput[]> {
|
|
261
|
+
// Wait for metadata check to complete if in progress
|
|
262
|
+
if (this.#metadataPromise) {
|
|
263
|
+
await this.#metadataPromise;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
logger().debug({ msg: "listing actors via engine api", name });
|
|
267
|
+
|
|
268
|
+
const response = await listActorsByName(this.#config, name);
|
|
269
|
+
|
|
270
|
+
return response.actors.map((actor) => ({
|
|
271
|
+
actorId: actor.actor_id,
|
|
272
|
+
name: actor.name,
|
|
273
|
+
key: deserializeActorKey(actor.key),
|
|
274
|
+
createTs: actor.create_ts,
|
|
275
|
+
}));
|
|
276
|
+
}
|
|
277
|
+
|
|
285
278
|
async destroyActor(actorId: string): Promise<void> {
|
|
286
279
|
// Wait for metadata check to complete if in progress
|
|
287
280
|
if (this.#metadataPromise) {
|
|
@@ -316,8 +309,6 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
316
309
|
actorId: string,
|
|
317
310
|
encoding: Encoding,
|
|
318
311
|
params: unknown,
|
|
319
|
-
connId?: string,
|
|
320
|
-
connToken?: string,
|
|
321
312
|
): Promise<UniversalWebSocket> {
|
|
322
313
|
// Wait for metadata check to complete if in progress
|
|
323
314
|
if (this.#metadataPromise) {
|
|
@@ -330,8 +321,6 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
330
321
|
actorId,
|
|
331
322
|
encoding,
|
|
332
323
|
params,
|
|
333
|
-
connId,
|
|
334
|
-
connToken,
|
|
335
324
|
);
|
|
336
325
|
}
|
|
337
326
|
|
|
@@ -358,8 +347,6 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
358
347
|
actorId: string,
|
|
359
348
|
encoding: Encoding,
|
|
360
349
|
params: unknown,
|
|
361
|
-
connId?: string,
|
|
362
|
-
connToken?: string,
|
|
363
350
|
): Promise<Response> {
|
|
364
351
|
// Wait for metadata check to complete if in progress
|
|
365
352
|
if (this.#metadataPromise) {
|
|
@@ -385,8 +372,6 @@ export class RemoteManagerDriver implements ManagerDriver {
|
|
|
385
372
|
this.#config,
|
|
386
373
|
encoding,
|
|
387
374
|
params,
|
|
388
|
-
connId,
|
|
389
|
-
connToken,
|
|
390
375
|
);
|
|
391
376
|
const args = await createWebSocketProxy(c, wsGuardUrl, protocols);
|
|
392
377
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { Context as HonoContext } from "hono";
|
|
2
2
|
import type { WSContext } from "hono/ws";
|
|
3
|
+
import type { UpgradeWebSocketArgs } from "@/actor/router-websocket-endpoints";
|
|
3
4
|
import { stringifyError } from "@/common/utils";
|
|
4
5
|
import { importWebSocket } from "@/common/websocket";
|
|
5
|
-
import type { UpgradeWebSocketArgs } from "@/mod";
|
|
6
6
|
import { logger } from "./log";
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "../../../dist/schemas/actor-persist/
|
|
1
|
+
export * from "../../../dist/schemas/actor-persist/v3";
|
|
@@ -3,39 +3,64 @@ import {
|
|
|
3
3
|
type MigrationFn,
|
|
4
4
|
} from "@/common/versioned-data";
|
|
5
5
|
import type * as v1 from "../../../dist/schemas/actor-persist/v1";
|
|
6
|
-
import * as v2 from "../../../dist/schemas/actor-persist/v2";
|
|
6
|
+
import type * as v2 from "../../../dist/schemas/actor-persist/v2";
|
|
7
|
+
import * as v3 from "../../../dist/schemas/actor-persist/v3";
|
|
7
8
|
|
|
8
|
-
export const CURRENT_VERSION =
|
|
9
|
+
export const CURRENT_VERSION = 3;
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
const migrations = new Map<number, MigrationFn<any, any>>([
|
|
12
|
+
[
|
|
13
|
+
1,
|
|
14
|
+
(v1Data: v1.PersistedActor): v2.PersistedActor => ({
|
|
15
|
+
...v1Data,
|
|
16
|
+
connections: v1Data.connections.map((conn) => ({
|
|
17
|
+
...conn,
|
|
18
|
+
hibernatableRequestId: null,
|
|
19
|
+
})),
|
|
20
|
+
hibernatableWebSockets: [],
|
|
21
|
+
}),
|
|
22
|
+
],
|
|
23
|
+
[
|
|
24
|
+
2,
|
|
25
|
+
(v2Data: v2.PersistedActor): v3.Actor => {
|
|
26
|
+
// Transform scheduled events from nested structure to flat structure
|
|
27
|
+
const scheduledEvents: v3.ScheduleEvent[] =
|
|
28
|
+
v2Data.scheduledEvents.map((event) => {
|
|
29
|
+
// Extract action and args from the kind wrapper
|
|
30
|
+
if (event.kind.tag === "GenericPersistedScheduleEvent") {
|
|
31
|
+
return {
|
|
32
|
+
eventId: event.eventId,
|
|
33
|
+
timestamp: event.timestamp,
|
|
34
|
+
action: event.kind.val.action,
|
|
35
|
+
args: event.kind.val.args,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Fallback for unknown kinds
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Unknown schedule event kind: ${event.kind.tag}`,
|
|
41
|
+
);
|
|
42
|
+
});
|
|
19
43
|
|
|
20
|
-
|
|
44
|
+
return {
|
|
45
|
+
input: v2Data.input,
|
|
46
|
+
hasInitialized: v2Data.hasInitialized,
|
|
47
|
+
state: v2Data.state,
|
|
48
|
+
scheduledEvents,
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
]);
|
|
21
53
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
...conn,
|
|
29
|
-
hibernatableRequestId: null,
|
|
30
|
-
})),
|
|
31
|
-
hibernatableWebSocket: [],
|
|
32
|
-
}),
|
|
33
|
-
);
|
|
54
|
+
export const ACTOR_VERSIONED = createVersionedDataHandler<v3.Actor>({
|
|
55
|
+
currentVersion: CURRENT_VERSION,
|
|
56
|
+
migrations,
|
|
57
|
+
serializeVersion: (data) => v3.encodeActor(data),
|
|
58
|
+
deserializeVersion: (bytes) => v3.decodeActor(bytes),
|
|
59
|
+
});
|
|
34
60
|
|
|
35
|
-
export const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
});
|
|
61
|
+
export const CONN_VERSIONED = createVersionedDataHandler<v3.Conn>({
|
|
62
|
+
currentVersion: CURRENT_VERSION,
|
|
63
|
+
migrations: new Map(),
|
|
64
|
+
serializeVersion: (data) => v3.encodeConn(data),
|
|
65
|
+
deserializeVersion: (bytes) => v3.decodeConn(bytes),
|
|
66
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "../../../dist/schemas/client-protocol/
|
|
1
|
+
export * from "../../../dist/schemas/client-protocol/v2";
|
|
@@ -2,52 +2,72 @@ import {
|
|
|
2
2
|
createVersionedDataHandler,
|
|
3
3
|
type MigrationFn,
|
|
4
4
|
} from "@/common/versioned-data";
|
|
5
|
-
import * as v1 from "../../../dist/schemas/client-protocol/v1";
|
|
5
|
+
import type * as v1 from "../../../dist/schemas/client-protocol/v1";
|
|
6
|
+
import * as v2 from "../../../dist/schemas/client-protocol/v2";
|
|
6
7
|
|
|
7
|
-
export const CURRENT_VERSION =
|
|
8
|
+
export const CURRENT_VERSION = 2;
|
|
8
9
|
|
|
9
10
|
const migrations = new Map<number, MigrationFn<any, any>>();
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
// Migration from v1 to v2: Remove connectionToken from Init message
|
|
13
|
+
migrations.set(1, (v1Data: v1.ToClient): v2.ToClient => {
|
|
14
|
+
// Handle Init message specifically to remove connectionToken
|
|
15
|
+
if (v1Data.body.tag === "Init") {
|
|
16
|
+
const { actorId, connectionId } = v1Data.body.val as v1.Init;
|
|
17
|
+
return {
|
|
18
|
+
body: {
|
|
19
|
+
tag: "Init",
|
|
20
|
+
val: {
|
|
21
|
+
actorId,
|
|
22
|
+
connectionId,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
// All other messages are unchanged
|
|
28
|
+
return v1Data as unknown as v2.ToClient;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const TO_SERVER_VERSIONED = createVersionedDataHandler<v2.ToServer>({
|
|
12
32
|
currentVersion: CURRENT_VERSION,
|
|
13
33
|
migrations,
|
|
14
|
-
serializeVersion: (data) =>
|
|
15
|
-
deserializeVersion: (bytes) =>
|
|
34
|
+
serializeVersion: (data) => v2.encodeToServer(data),
|
|
35
|
+
deserializeVersion: (bytes) => v2.decodeToServer(bytes),
|
|
16
36
|
});
|
|
17
37
|
|
|
18
|
-
export const TO_CLIENT_VERSIONED = createVersionedDataHandler<
|
|
38
|
+
export const TO_CLIENT_VERSIONED = createVersionedDataHandler<v2.ToClient>({
|
|
19
39
|
currentVersion: CURRENT_VERSION,
|
|
20
40
|
migrations,
|
|
21
|
-
serializeVersion: (data) =>
|
|
22
|
-
deserializeVersion: (bytes) =>
|
|
41
|
+
serializeVersion: (data) => v2.encodeToClient(data),
|
|
42
|
+
deserializeVersion: (bytes) => v2.decodeToClient(bytes),
|
|
23
43
|
});
|
|
24
44
|
|
|
25
45
|
export const HTTP_ACTION_REQUEST_VERSIONED =
|
|
26
|
-
createVersionedDataHandler<
|
|
46
|
+
createVersionedDataHandler<v2.HttpActionRequest>({
|
|
27
47
|
currentVersion: CURRENT_VERSION,
|
|
28
48
|
migrations,
|
|
29
|
-
serializeVersion: (data) =>
|
|
30
|
-
deserializeVersion: (bytes) =>
|
|
49
|
+
serializeVersion: (data) => v2.encodeHttpActionRequest(data),
|
|
50
|
+
deserializeVersion: (bytes) => v2.decodeHttpActionRequest(bytes),
|
|
31
51
|
});
|
|
32
52
|
|
|
33
53
|
export const HTTP_ACTION_RESPONSE_VERSIONED =
|
|
34
|
-
createVersionedDataHandler<
|
|
54
|
+
createVersionedDataHandler<v2.HttpActionResponse>({
|
|
35
55
|
currentVersion: CURRENT_VERSION,
|
|
36
56
|
migrations,
|
|
37
|
-
serializeVersion: (data) =>
|
|
38
|
-
deserializeVersion: (bytes) =>
|
|
57
|
+
serializeVersion: (data) => v2.encodeHttpActionResponse(data),
|
|
58
|
+
deserializeVersion: (bytes) => v2.decodeHttpActionResponse(bytes),
|
|
39
59
|
});
|
|
40
60
|
|
|
41
61
|
export const HTTP_RESPONSE_ERROR_VERSIONED =
|
|
42
|
-
createVersionedDataHandler<
|
|
62
|
+
createVersionedDataHandler<v2.HttpResponseError>({
|
|
43
63
|
currentVersion: CURRENT_VERSION,
|
|
44
64
|
migrations,
|
|
45
|
-
serializeVersion: (data) =>
|
|
46
|
-
deserializeVersion: (bytes) =>
|
|
65
|
+
serializeVersion: (data) => v2.encodeHttpResponseError(data),
|
|
66
|
+
deserializeVersion: (bytes) => v2.decodeHttpResponseError(bytes),
|
|
47
67
|
});
|
|
48
68
|
|
|
49
69
|
export const HTTP_RESOLVE_REQUEST_VERSIONED =
|
|
50
|
-
createVersionedDataHandler<
|
|
70
|
+
createVersionedDataHandler<v2.HttpResolveRequest>({
|
|
51
71
|
currentVersion: CURRENT_VERSION,
|
|
52
72
|
migrations,
|
|
53
73
|
serializeVersion: (_) => new Uint8Array(),
|
|
@@ -55,9 +75,9 @@ export const HTTP_RESOLVE_REQUEST_VERSIONED =
|
|
|
55
75
|
});
|
|
56
76
|
|
|
57
77
|
export const HTTP_RESOLVE_RESPONSE_VERSIONED =
|
|
58
|
-
createVersionedDataHandler<
|
|
78
|
+
createVersionedDataHandler<v2.HttpResolveResponse>({
|
|
59
79
|
currentVersion: CURRENT_VERSION,
|
|
60
80
|
migrations,
|
|
61
|
-
serializeVersion: (data) =>
|
|
62
|
-
deserializeVersion: (bytes) =>
|
|
81
|
+
serializeVersion: (data) => v2.encodeHttpResolveResponse(data),
|
|
82
|
+
deserializeVersion: (bytes) => v2.decodeHttpResolveResponse(bytes),
|
|
63
83
|
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// Helper schemas
|
|
4
|
+
const UintSchema = z.bigint();
|
|
5
|
+
const OptionalUintSchema = UintSchema.nullable();
|
|
6
|
+
|
|
7
|
+
// MARK: Message To Client
|
|
8
|
+
export const InitSchema = z.object({
|
|
9
|
+
actorId: z.string(),
|
|
10
|
+
connectionId: z.string(),
|
|
11
|
+
});
|
|
12
|
+
export type Init = z.infer<typeof InitSchema>;
|
|
13
|
+
|
|
14
|
+
export const ErrorSchema = z.object({
|
|
15
|
+
group: z.string(),
|
|
16
|
+
code: z.string(),
|
|
17
|
+
message: z.string(),
|
|
18
|
+
metadata: z.unknown().optional(),
|
|
19
|
+
actionId: OptionalUintSchema,
|
|
20
|
+
});
|
|
21
|
+
export type Error = z.infer<typeof ErrorSchema>;
|
|
22
|
+
|
|
23
|
+
export const ActionResponseSchema = z.object({
|
|
24
|
+
id: UintSchema,
|
|
25
|
+
output: z.unknown(),
|
|
26
|
+
});
|
|
27
|
+
export type ActionResponse = z.infer<typeof ActionResponseSchema>;
|
|
28
|
+
|
|
29
|
+
export const EventSchema = z.object({
|
|
30
|
+
name: z.string(),
|
|
31
|
+
args: z.unknown(),
|
|
32
|
+
});
|
|
33
|
+
export type Event = z.infer<typeof EventSchema>;
|
|
34
|
+
|
|
35
|
+
export const ToClientBodySchema = z.discriminatedUnion("tag", [
|
|
36
|
+
z.object({ tag: z.literal("Init"), val: InitSchema }),
|
|
37
|
+
z.object({ tag: z.literal("Error"), val: ErrorSchema }),
|
|
38
|
+
z.object({ tag: z.literal("ActionResponse"), val: ActionResponseSchema }),
|
|
39
|
+
z.object({ tag: z.literal("Event"), val: EventSchema }),
|
|
40
|
+
]);
|
|
41
|
+
export type ToClientBody = z.infer<typeof ToClientBodySchema>;
|
|
42
|
+
|
|
43
|
+
export const ToClientSchema = z.object({
|
|
44
|
+
body: ToClientBodySchema,
|
|
45
|
+
});
|
|
46
|
+
export type ToClient = z.infer<typeof ToClientSchema>;
|
|
47
|
+
|
|
48
|
+
// MARK: Message To Server
|
|
49
|
+
export const ActionRequestSchema = z.object({
|
|
50
|
+
id: UintSchema,
|
|
51
|
+
name: z.string(),
|
|
52
|
+
args: z.unknown(),
|
|
53
|
+
});
|
|
54
|
+
export type ActionRequest = z.infer<typeof ActionRequestSchema>;
|
|
55
|
+
|
|
56
|
+
export const SubscriptionRequestSchema = z.object({
|
|
57
|
+
eventName: z.string(),
|
|
58
|
+
subscribe: z.boolean(),
|
|
59
|
+
});
|
|
60
|
+
export type SubscriptionRequest = z.infer<typeof SubscriptionRequestSchema>;
|
|
61
|
+
|
|
62
|
+
export const ToServerBodySchema = z.discriminatedUnion("tag", [
|
|
63
|
+
z.object({ tag: z.literal("ActionRequest"), val: ActionRequestSchema }),
|
|
64
|
+
z.object({
|
|
65
|
+
tag: z.literal("SubscriptionRequest"),
|
|
66
|
+
val: SubscriptionRequestSchema,
|
|
67
|
+
}),
|
|
68
|
+
]);
|
|
69
|
+
export type ToServerBody = z.infer<typeof ToServerBodySchema>;
|
|
70
|
+
|
|
71
|
+
export const ToServerSchema = z.object({
|
|
72
|
+
body: ToServerBodySchema,
|
|
73
|
+
});
|
|
74
|
+
export type ToServer = z.infer<typeof ToServerSchema>;
|
|
75
|
+
|
|
76
|
+
// MARK: HTTP Action
|
|
77
|
+
export const HttpActionRequestSchema = z.object({
|
|
78
|
+
args: z.unknown(),
|
|
79
|
+
});
|
|
80
|
+
export type HttpActionRequest = z.infer<typeof HttpActionRequestSchema>;
|
|
81
|
+
|
|
82
|
+
export const HttpActionResponseSchema = z.object({
|
|
83
|
+
output: z.unknown(),
|
|
84
|
+
});
|
|
85
|
+
export type HttpActionResponse = z.infer<typeof HttpActionResponseSchema>;
|
|
86
|
+
|
|
87
|
+
// MARK: HTTP Error
|
|
88
|
+
export const HttpResponseErrorSchema = z.object({
|
|
89
|
+
group: z.string(),
|
|
90
|
+
code: z.string(),
|
|
91
|
+
message: z.string(),
|
|
92
|
+
metadata: z.unknown().optional(),
|
|
93
|
+
});
|
|
94
|
+
export type HttpResponseError = z.infer<typeof HttpResponseErrorSchema>;
|
|
95
|
+
|
|
96
|
+
// MARK: HTTP Resolve
|
|
97
|
+
export const HttpResolveRequestSchema = z.null();
|
|
98
|
+
export type HttpResolveRequest = z.infer<typeof HttpResolveRequestSchema>;
|
|
99
|
+
|
|
100
|
+
export const HttpResolveResponseSchema = z.object({
|
|
101
|
+
actorId: z.string(),
|
|
102
|
+
});
|
|
103
|
+
export type HttpResolveResponse = z.infer<typeof HttpResolveResponseSchema>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from "../../../dist/schemas/file-system-driver/
|
|
1
|
+
export * from "../../../dist/schemas/file-system-driver/v2";
|
|
@@ -2,27 +2,50 @@ import {
|
|
|
2
2
|
createVersionedDataHandler,
|
|
3
3
|
type MigrationFn,
|
|
4
4
|
} from "@/common/versioned-data";
|
|
5
|
-
import
|
|
5
|
+
import { bufferToArrayBuffer } from "@/utils";
|
|
6
|
+
import type * as v1 from "../../../dist/schemas/file-system-driver/v1";
|
|
7
|
+
import * as v2 from "../../../dist/schemas/file-system-driver/v2";
|
|
6
8
|
|
|
7
|
-
export const CURRENT_VERSION =
|
|
9
|
+
export const CURRENT_VERSION = 2;
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
const migrations = new Map<number, MigrationFn<any, any>>([
|
|
12
|
+
[
|
|
13
|
+
2,
|
|
14
|
+
(v1State: v1.ActorState): v2.ActorState => {
|
|
15
|
+
// Create a new kvStorage list with the legacy persist data
|
|
16
|
+
const kvStorage: v2.ActorKvEntry[] = [];
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
// Store the legacy persist data under key [1]
|
|
19
|
+
if (v1State.persistedData) {
|
|
20
|
+
// Key [1] as Uint8Array
|
|
21
|
+
const key = new Uint8Array([1]);
|
|
22
|
+
kvStorage.push({
|
|
23
|
+
key: bufferToArrayBuffer(key),
|
|
24
|
+
value: v1State.persistedData,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
13
27
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
28
|
+
return {
|
|
29
|
+
actorId: v1State.actorId,
|
|
30
|
+
name: v1State.name,
|
|
31
|
+
key: v1State.key,
|
|
32
|
+
kvStorage,
|
|
33
|
+
createdAt: v1State.createdAt,
|
|
34
|
+
};
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
]);
|
|
21
38
|
|
|
22
|
-
export const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
39
|
+
export const ACTOR_STATE_VERSIONED = createVersionedDataHandler<v2.ActorState>({
|
|
40
|
+
currentVersion: CURRENT_VERSION,
|
|
41
|
+
migrations,
|
|
42
|
+
serializeVersion: (data) => v2.encodeActorState(data),
|
|
43
|
+
deserializeVersion: (bytes) => v2.decodeActorState(bytes),
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
export const ACTOR_ALARM_VERSIONED = createVersionedDataHandler<v2.ActorAlarm>({
|
|
47
|
+
currentVersion: CURRENT_VERSION,
|
|
48
|
+
migrations,
|
|
49
|
+
serializeVersion: (data) => v2.encodeActorAlarm(data),
|
|
50
|
+
deserializeVersion: (bytes) => v2.decodeActorAlarm(bytes),
|
|
51
|
+
});
|
package/src/serde.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as cbor from "cbor-x";
|
|
2
2
|
import invariant from "invariant";
|
|
3
|
+
import type { z } from "zod";
|
|
3
4
|
import { assertUnreachable } from "@/common/utils";
|
|
4
5
|
import type { VersionedDataHandler } from "@/common/versioned-data";
|
|
5
6
|
import type { Encoding } from "@/mod";
|
|
@@ -52,46 +53,65 @@ export function wsBinaryTypeForEncoding(
|
|
|
52
53
|
}
|
|
53
54
|
}
|
|
54
55
|
|
|
55
|
-
export function serializeWithEncoding<T>(
|
|
56
|
+
export function serializeWithEncoding<TBare, TJson, T = TBare>(
|
|
56
57
|
encoding: Encoding,
|
|
57
58
|
value: T,
|
|
58
|
-
versionedDataHandler: VersionedDataHandler<
|
|
59
|
+
versionedDataHandler: VersionedDataHandler<TBare> | undefined,
|
|
60
|
+
zodSchema: z.ZodType<TJson>,
|
|
61
|
+
toJson: (value: T) => TJson,
|
|
62
|
+
toBare: (value: T) => TBare,
|
|
59
63
|
): Uint8Array | string {
|
|
60
64
|
if (encoding === "json") {
|
|
61
|
-
|
|
65
|
+
const jsonValue = toJson(value);
|
|
66
|
+
const validated = zodSchema.parse(jsonValue);
|
|
67
|
+
return jsonStringifyCompat(validated);
|
|
62
68
|
} else if (encoding === "cbor") {
|
|
63
|
-
|
|
69
|
+
const jsonValue = toJson(value);
|
|
70
|
+
const validated = zodSchema.parse(jsonValue);
|
|
71
|
+
return cbor.encode(validated);
|
|
64
72
|
} else if (encoding === "bare") {
|
|
65
73
|
if (!versionedDataHandler) {
|
|
66
74
|
throw new Error(
|
|
67
75
|
"VersionedDataHandler is required for 'bare' encoding",
|
|
68
76
|
);
|
|
69
77
|
}
|
|
70
|
-
|
|
78
|
+
const bareValue = toBare(value);
|
|
79
|
+
return versionedDataHandler.serializeWithEmbeddedVersion(bareValue);
|
|
71
80
|
} else {
|
|
72
81
|
assertUnreachable(encoding);
|
|
73
82
|
}
|
|
74
83
|
}
|
|
75
84
|
|
|
76
|
-
export function deserializeWithEncoding<T>(
|
|
85
|
+
export function deserializeWithEncoding<TBare, TJson, T = TBare>(
|
|
77
86
|
encoding: Encoding,
|
|
78
87
|
buffer: Uint8Array | string,
|
|
79
|
-
versionedDataHandler: VersionedDataHandler<
|
|
88
|
+
versionedDataHandler: VersionedDataHandler<TBare> | undefined,
|
|
89
|
+
zodSchema: z.ZodType<TJson>,
|
|
90
|
+
fromJson: (value: TJson) => T,
|
|
91
|
+
fromBare: (value: TBare) => T,
|
|
80
92
|
): T {
|
|
81
93
|
if (encoding === "json") {
|
|
94
|
+
let parsed: unknown;
|
|
82
95
|
if (typeof buffer === "string") {
|
|
83
|
-
|
|
96
|
+
parsed = jsonParseCompat(buffer);
|
|
84
97
|
} else {
|
|
85
98
|
const decoder = new TextDecoder("utf-8");
|
|
86
99
|
const jsonString = decoder.decode(buffer);
|
|
87
|
-
|
|
100
|
+
parsed = jsonParseCompat(jsonString);
|
|
88
101
|
}
|
|
102
|
+
const validated = zodSchema.parse(parsed);
|
|
103
|
+
return fromJson(validated);
|
|
89
104
|
} else if (encoding === "cbor") {
|
|
90
105
|
invariant(
|
|
91
106
|
typeof buffer !== "string",
|
|
92
107
|
"buffer cannot be string for cbor encoding",
|
|
93
108
|
);
|
|
94
|
-
|
|
109
|
+
// Decode CBOR to get JavaScript values (similar to JSON.parse)
|
|
110
|
+
const decoded: unknown = cbor.decode(buffer);
|
|
111
|
+
// Validate with Zod schema (CBOR produces same structure as JSON)
|
|
112
|
+
const validated = zodSchema.parse(decoded);
|
|
113
|
+
// CBOR decoding produces JS objects, use fromJson
|
|
114
|
+
return fromJson(validated);
|
|
95
115
|
} else if (encoding === "bare") {
|
|
96
116
|
invariant(
|
|
97
117
|
typeof buffer !== "string",
|
|
@@ -102,7 +122,9 @@ export function deserializeWithEncoding<T>(
|
|
|
102
122
|
"VersionedDataHandler is required for 'bare' encoding",
|
|
103
123
|
);
|
|
104
124
|
}
|
|
105
|
-
|
|
125
|
+
const bareValue =
|
|
126
|
+
versionedDataHandler.deserializeWithEmbeddedVersion(buffer);
|
|
127
|
+
return fromBare(bareValue);
|
|
106
128
|
} else {
|
|
107
129
|
assertUnreachable(encoding);
|
|
108
130
|
}
|