@xyo-network/dapp-kit-port 3.0.1 → 3.1.0
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 +22 -0
- package/dist/browser/applicationPortClient.d.ts.map +1 -1
- package/dist/browser/applicationPortHost.d.ts.map +1 -1
- package/dist/browser/applicationPortModel.d.ts +39 -18
- package/dist/browser/applicationPortModel.d.ts.map +1 -1
- package/dist/browser/applicationPortOperations.d.ts +4 -0
- package/dist/browser/applicationPortOperations.d.ts.map +1 -0
- package/dist/browser/applicationPortWire.d.ts +396 -3
- package/dist/browser/applicationPortWire.d.ts.map +1 -1
- package/dist/browser/engineApplicationPortHost.d.ts.map +1 -1
- package/dist/browser/index.mjs +90 -34
- package/dist/browser/index.mjs.map +4 -4
- package/dist/browser/webSocketApplicationPortClient.d.ts +3 -1
- package/dist/browser/webSocketApplicationPortClient.d.ts.map +1 -1
- package/dist/node/applicationPortClient.d.ts.map +1 -1
- package/dist/node/applicationPortHost.d.ts.map +1 -1
- package/dist/node/applicationPortModel.d.ts +39 -18
- package/dist/node/applicationPortModel.d.ts.map +1 -1
- package/dist/node/applicationPortOperations.d.ts +4 -0
- package/dist/node/applicationPortOperations.d.ts.map +1 -0
- package/dist/node/applicationPortWire.d.ts +396 -3
- package/dist/node/applicationPortWire.d.ts.map +1 -1
- package/dist/node/engineApplicationPortHost.d.ts.map +1 -1
- package/dist/node/index.mjs +90 -34
- package/dist/node/index.mjs.map +4 -4
- package/dist/node/webSocketApplicationPortClient.d.ts +3 -1
- package/dist/node/webSocketApplicationPortClient.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/browser/index.mjs
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
canonicalizeIJson,
|
|
4
4
|
PortAttachmentGrantZod,
|
|
5
|
+
PortFrameSchemaVersionZod,
|
|
6
|
+
portStreamResumeNextSequence,
|
|
7
|
+
portStreamTerminalMatches,
|
|
5
8
|
validatePortFrame
|
|
6
9
|
} from "@xyo-network/dapp-kit";
|
|
7
10
|
|
|
8
11
|
// src/applicationPortModel.ts
|
|
9
|
-
import {
|
|
12
|
+
import { PortFrameAnyVersionZod, PortFrameSchema } from "@xyo-network/dapp-kit";
|
|
10
13
|
var ApplicationPortProxyErrorCode = {
|
|
11
14
|
cancelled: "port.cancelled",
|
|
12
15
|
detached: "port.detached",
|
|
@@ -58,7 +61,7 @@ function applicationPortOperationGrant(grant, portId, operationId) {
|
|
|
58
61
|
function applicationPortFrameBase(grant, frame) {
|
|
59
62
|
return {
|
|
60
63
|
schema: PortFrameSchema,
|
|
61
|
-
schemaVersion: 1,
|
|
64
|
+
schemaVersion: frame.schemaVersion ?? 1,
|
|
62
65
|
dappId: grant.dappId,
|
|
63
66
|
protocolVersion: grant.protocolVersion,
|
|
64
67
|
planId: grant.planId,
|
|
@@ -72,7 +75,7 @@ function applicationPortFrameBase(grant, frame) {
|
|
|
72
75
|
};
|
|
73
76
|
}
|
|
74
77
|
function parseApplicationPortFrame(value) {
|
|
75
|
-
return
|
|
78
|
+
return PortFrameAnyVersionZod.parse(value);
|
|
76
79
|
}
|
|
77
80
|
function applicationPortErrorFrame(grant, frame, error) {
|
|
78
81
|
return parseApplicationPortFrame({
|
|
@@ -87,13 +90,21 @@ var ApplicationPortStreamInstance = class {
|
|
|
87
90
|
requestId;
|
|
88
91
|
streamId;
|
|
89
92
|
client;
|
|
93
|
+
openingProgress;
|
|
90
94
|
state;
|
|
91
95
|
constructor(client, state, streamId) {
|
|
92
96
|
this.client = client;
|
|
97
|
+
this.openingProgress = Object.freeze({
|
|
98
|
+
nextSequence: state.lastAcceptedSequence + 1,
|
|
99
|
+
...state.resumeCursor === void 0 ? {} : { resumeCursor: state.resumeCursor }
|
|
100
|
+
});
|
|
93
101
|
this.requestId = state.frame.requestId;
|
|
94
102
|
this.state = state;
|
|
95
103
|
this.streamId = streamId;
|
|
96
104
|
}
|
|
105
|
+
get initialProgress() {
|
|
106
|
+
return this.openingProgress;
|
|
107
|
+
}
|
|
97
108
|
[Symbol.asyncIterator]() {
|
|
98
109
|
return this;
|
|
99
110
|
}
|
|
@@ -119,7 +130,11 @@ var ApplicationPortClientInstance = class {
|
|
|
119
130
|
options;
|
|
120
131
|
requests = /* @__PURE__ */ new Map();
|
|
121
132
|
constructor(options) {
|
|
122
|
-
this.options = {
|
|
133
|
+
this.options = {
|
|
134
|
+
...options,
|
|
135
|
+
frameSchemaVersion: PortFrameSchemaVersionZod.parse(options.frameSchemaVersion ?? 1),
|
|
136
|
+
grant: PortAttachmentGrantZod.parse(options.grant)
|
|
137
|
+
};
|
|
123
138
|
this.listener = (message) => this.receive(message);
|
|
124
139
|
options.endpoint.addMessageListener(this.listener);
|
|
125
140
|
options.endpoint.start?.();
|
|
@@ -188,17 +203,21 @@ var ApplicationPortClientInstance = class {
|
|
|
188
203
|
);
|
|
189
204
|
}
|
|
190
205
|
this.verifyCredit(options.credit, 0, grant);
|
|
206
|
+
const version = this.options.frameSchemaVersion ?? 1;
|
|
207
|
+
if (version === 1 && (options.lastAcceptedSequence === void 0 || options.nextSequence !== void 0) || version === 2 && (options.nextSequence === void 0 || options.lastAcceptedSequence !== void 0)) {
|
|
208
|
+
throw new ApplicationPortProxyError(ApplicationPortProxyErrorCode.streamStateInvalid, "Resume progress does not match the selected frame schema version");
|
|
209
|
+
}
|
|
191
210
|
const frame = parseApplicationPortFrame({
|
|
192
211
|
...this.newFrameBase(options),
|
|
193
212
|
frameKind: "stream-resume",
|
|
194
213
|
streamId: options.streamId,
|
|
195
|
-
lastAcceptedSequence: options.lastAcceptedSequence,
|
|
214
|
+
...version === 2 ? { nextSequence: options.nextSequence } : { lastAcceptedSequence: options.lastAcceptedSequence },
|
|
196
215
|
resumeCursor: options.resumeCursor,
|
|
197
216
|
credit: options.credit
|
|
198
217
|
});
|
|
199
218
|
const state = this.streamState(frame, grant, options.credit);
|
|
200
219
|
state.availableCredit = options.credit;
|
|
201
|
-
state.lastAcceptedSequence =
|
|
220
|
+
state.lastAcceptedSequence = portStreamResumeNextSequence(frame) - 1;
|
|
202
221
|
state.resumeCursor = options.resumeCursor;
|
|
203
222
|
state.streamId = options.streamId;
|
|
204
223
|
this.requests.set(frame.requestId, state);
|
|
@@ -269,12 +288,13 @@ var ApplicationPortClientInstance = class {
|
|
|
269
288
|
}
|
|
270
289
|
return applicationPortFrameBase(this.options.grant, {
|
|
271
290
|
...options,
|
|
291
|
+
schemaVersion: this.options.frameSchemaVersion,
|
|
272
292
|
requestId: this.options.nextRequestId()
|
|
273
293
|
});
|
|
274
294
|
}
|
|
275
295
|
openStream(state, frame) {
|
|
276
296
|
const grant = state.grant;
|
|
277
|
-
const resumeMismatch = state.
|
|
297
|
+
const resumeMismatch = state.frame.frameKind === "stream-resume" && frame.nextSequence !== state.lastAcceptedSequence + 1;
|
|
278
298
|
if (state.isOpen || frame.resumable !== grant.resumable || state.streamId !== void 0 && state.streamId !== frame.streamId || resumeMismatch) {
|
|
279
299
|
this.fail(state, new ApplicationPortProxyError(
|
|
280
300
|
ApplicationPortProxyErrorCode.streamStateInvalid,
|
|
@@ -299,6 +319,7 @@ var ApplicationPortClientInstance = class {
|
|
|
299
319
|
if (this.isClosed) return;
|
|
300
320
|
const result = validatePortFrame(value, {
|
|
301
321
|
authenticatedPrincipalId: this.options.authenticatedPrincipalId,
|
|
322
|
+
frameSchemaVersion: this.options.frameSchemaVersion,
|
|
302
323
|
grant: this.options.grant,
|
|
303
324
|
now: this.options.now()
|
|
304
325
|
});
|
|
@@ -437,7 +458,7 @@ var ApplicationPortClientInstance = class {
|
|
|
437
458
|
};
|
|
438
459
|
}
|
|
439
460
|
terminateStream(state, frame) {
|
|
440
|
-
if (frame
|
|
461
|
+
if (!portStreamTerminalMatches(frame, state.lastAcceptedSequence + 1)) {
|
|
441
462
|
this.fail(state, new ApplicationPortProxyError(
|
|
442
463
|
ApplicationPortProxyErrorCode.streamStateInvalid,
|
|
443
464
|
"Stream terminal sequence does not match accepted items"
|
|
@@ -464,29 +485,31 @@ function createApplicationPortClient(options) {
|
|
|
464
485
|
// src/applicationPortHost.ts
|
|
465
486
|
import {
|
|
466
487
|
PortAttachmentGrantZod as PortAttachmentGrantZod2,
|
|
488
|
+
PortFrameSchemaVersionZod as PortFrameSchemaVersionZod2,
|
|
489
|
+
PortStreamProgressUnsupportedCode,
|
|
490
|
+
portStreamResumeNextSequence as portStreamResumeNextSequence2,
|
|
491
|
+
portStreamTerminalProgress,
|
|
467
492
|
validatePortFrame as validatePortFrame2
|
|
468
493
|
} from "@xyo-network/dapp-kit";
|
|
469
|
-
|
|
494
|
+
|
|
495
|
+
// src/applicationPortOperations.ts
|
|
496
|
+
function registeredApplicationPortOperations(attachment, values) {
|
|
470
497
|
const operations2 = /* @__PURE__ */ new Map();
|
|
471
|
-
for (const operation of
|
|
498
|
+
for (const operation of values) {
|
|
472
499
|
const key2 = applicationPortOperationKey(operation.portId, operation.operationId);
|
|
473
|
-
const grant = applicationPortOperationGrant(
|
|
500
|
+
const grant = applicationPortOperationGrant(attachment, operation.portId, operation.operationId);
|
|
474
501
|
if (operations2.has(key2)) {
|
|
475
|
-
throw new ApplicationPortProxyError(
|
|
476
|
-
ApplicationPortProxyErrorCode.duplicateRequest,
|
|
477
|
-
`Application-port operation is registered more than once: ${operation.portId}.${operation.operationId}`
|
|
478
|
-
);
|
|
502
|
+
throw new ApplicationPortProxyError(ApplicationPortProxyErrorCode.duplicateRequest, `Application-port operation is registered more than once: ${operation.portId}.${operation.operationId}`);
|
|
479
503
|
}
|
|
480
504
|
if (grant?.streaming !== operation.streaming) {
|
|
481
|
-
throw new ApplicationPortProxyError(
|
|
482
|
-
ApplicationPortProxyErrorCode.operationKindMismatch,
|
|
483
|
-
`Registered operation conflicts with attachment grant: ${operation.portId}.${operation.operationId}`
|
|
484
|
-
);
|
|
505
|
+
throw new ApplicationPortProxyError(ApplicationPortProxyErrorCode.operationKindMismatch, `Registered operation conflicts with attachment grant: ${operation.portId}.${operation.operationId}`);
|
|
485
506
|
}
|
|
486
507
|
operations2.set(key2, operation);
|
|
487
508
|
}
|
|
488
509
|
return operations2;
|
|
489
510
|
}
|
|
511
|
+
|
|
512
|
+
// src/applicationPortHost.ts
|
|
490
513
|
var ApplicationPortHostInstance = class {
|
|
491
514
|
cleanupErrors = [];
|
|
492
515
|
closePromise;
|
|
@@ -497,8 +520,12 @@ var ApplicationPortHostInstance = class {
|
|
|
497
520
|
ownedRequests = /* @__PURE__ */ new Set();
|
|
498
521
|
requests = /* @__PURE__ */ new Map();
|
|
499
522
|
constructor(options) {
|
|
500
|
-
this.options = {
|
|
501
|
-
|
|
523
|
+
this.options = {
|
|
524
|
+
...options,
|
|
525
|
+
frameSchemaVersion: PortFrameSchemaVersionZod2.parse(options.frameSchemaVersion ?? 1),
|
|
526
|
+
grant: PortAttachmentGrantZod2.parse(options.grant)
|
|
527
|
+
};
|
|
528
|
+
this.operations = registeredApplicationPortOperations(this.options.grant, this.options.operations);
|
|
502
529
|
this.listener = (message) => void this.receive(message);
|
|
503
530
|
options.endpoint.addMessageListener(this.listener);
|
|
504
531
|
options.endpoint.start?.();
|
|
@@ -630,7 +657,7 @@ var ApplicationPortHostInstance = class {
|
|
|
630
657
|
isCancelled: false,
|
|
631
658
|
isTerminal: false,
|
|
632
659
|
kind: "stream",
|
|
633
|
-
lastSequence: frame.frameKind === "stream-resume" ? frame
|
|
660
|
+
lastSequence: frame.frameKind === "stream-resume" ? portStreamResumeNextSequence2(frame) - 1 : -1,
|
|
634
661
|
...frame.frameKind === "stream-resume" ? { resumeCursor: frame.resumeCursor } : {}
|
|
635
662
|
};
|
|
636
663
|
this.requests.set(frame.requestId, state);
|
|
@@ -667,6 +694,7 @@ var ApplicationPortHostInstance = class {
|
|
|
667
694
|
if (this.isClosed) return;
|
|
668
695
|
const result = validatePortFrame2(value, {
|
|
669
696
|
authenticatedPrincipalId: this.options.authenticatedPrincipalId,
|
|
697
|
+
frameSchemaVersion: this.options.frameSchemaVersion,
|
|
670
698
|
grant: this.options.grant,
|
|
671
699
|
now: this.options.now()
|
|
672
700
|
});
|
|
@@ -783,18 +811,25 @@ var ApplicationPortHostInstance = class {
|
|
|
783
811
|
const read = await source.next(state.controller.signal);
|
|
784
812
|
if (state.isCancelled || this.isClosed) return false;
|
|
785
813
|
if (read.done) {
|
|
814
|
+
if (state.frame.schemaVersion === 1 && state.lastSequence < 0) {
|
|
815
|
+
this.terminateStreamWithError(state, void 0, PortStreamProgressUnsupportedCode);
|
|
816
|
+
return false;
|
|
817
|
+
}
|
|
786
818
|
state.isTerminal = true;
|
|
787
819
|
this.post(parseApplicationPortFrame({
|
|
788
820
|
...applicationPortFrameBase(this.options.grant, state.frame),
|
|
789
821
|
frameKind: "stream-close",
|
|
790
822
|
streamId: source.streamId,
|
|
791
|
-
|
|
823
|
+
...portStreamTerminalProgress(state.frame.schemaVersion, state.lastSequence + 1),
|
|
792
824
|
...read.resumeCursor === void 0 ? {} : { resumeCursor: read.resumeCursor }
|
|
793
825
|
}));
|
|
794
826
|
this.requests.delete(state.frame.requestId);
|
|
795
827
|
this.ownedRequests.delete(state);
|
|
796
828
|
return false;
|
|
797
829
|
}
|
|
830
|
+
if (!Number.isSafeInteger(state.lastSequence + 2)) {
|
|
831
|
+
throw new ApplicationPortProxyError(ApplicationPortProxyErrorCode.streamStateInvalid, "Stream successor exceeds safe integer progress");
|
|
832
|
+
}
|
|
798
833
|
if (source.resumable && read.value.resumeCursor === void 0) {
|
|
799
834
|
throw new ApplicationPortProxyError(
|
|
800
835
|
ApplicationPortProxyErrorCode.streamStateInvalid,
|
|
@@ -831,7 +866,8 @@ var ApplicationPortHostInstance = class {
|
|
|
831
866
|
}
|
|
832
867
|
return await operation.resume({
|
|
833
868
|
...context,
|
|
834
|
-
|
|
869
|
+
nextSequence: portStreamResumeNextSequence2(frame),
|
|
870
|
+
...portStreamResumeNextSequence2(frame) > 0 ? { lastAcceptedSequence: portStreamResumeNextSequence2(frame) - 1 } : {},
|
|
835
871
|
resumeCursor: frame.resumeCursor,
|
|
836
872
|
streamId: frame.streamId
|
|
837
873
|
});
|
|
@@ -855,11 +891,12 @@ var ApplicationPortHostInstance = class {
|
|
|
855
891
|
if (source === void 0 || state.isTerminal || this.isClosed) return;
|
|
856
892
|
state.isTerminal = true;
|
|
857
893
|
const error = code === void 0 ? this.mapError(state.frame, cause) : { code, retriable: false };
|
|
858
|
-
this.
|
|
894
|
+
if (state.frame.schemaVersion === 1 && state.lastSequence < 0) this.postError(state.frame, PortStreamProgressUnsupportedCode);
|
|
895
|
+
else this.post(parseApplicationPortFrame({
|
|
859
896
|
...applicationPortFrameBase(this.options.grant, state.frame),
|
|
860
897
|
frameKind: "stream-error",
|
|
861
898
|
streamId: source.streamId,
|
|
862
|
-
|
|
899
|
+
...portStreamTerminalProgress(state.frame.schemaVersion, state.lastSequence + 1),
|
|
863
900
|
...state.resumeCursor === void 0 ? {} : { resumeCursor: state.resumeCursor },
|
|
864
901
|
error
|
|
865
902
|
}));
|
|
@@ -869,8 +906,8 @@ var ApplicationPortHostInstance = class {
|
|
|
869
906
|
void this.cleanupStream(state, ApplicationPortProxyErrorCode.hostFailure);
|
|
870
907
|
}
|
|
871
908
|
verifyStreamSource(source, frame, grant) {
|
|
872
|
-
const resumeMismatch = frame.frameKind === "stream-resume" && (source.streamId !== frame.streamId || source.nextSequence !== frame
|
|
873
|
-
if (source.resumable !== grant.resumable || source.resumable && source.resumeCursor === void 0 || resumeMismatch) {
|
|
909
|
+
const resumeMismatch = frame.frameKind === "stream-resume" && (source.streamId !== frame.streamId || source.nextSequence !== portStreamResumeNextSequence2(frame));
|
|
910
|
+
if (!Number.isSafeInteger(source.nextSequence) || source.nextSequence < 0 || source.resumable !== grant.resumable || source.resumable && source.resumeCursor === void 0 || resumeMismatch) {
|
|
874
911
|
throw new ApplicationPortProxyError(
|
|
875
912
|
ApplicationPortProxyErrorCode.streamStateInvalid,
|
|
876
913
|
"Stream source conflicts with its grant or resume request"
|
|
@@ -888,7 +925,7 @@ import {
|
|
|
888
925
|
IdentifierZod,
|
|
889
926
|
parseStrictJsonText,
|
|
890
927
|
PortAttachmentGrantZod as PortAttachmentGrantZod3,
|
|
891
|
-
|
|
928
|
+
PortFrameAnyVersionZod as PortFrameAnyVersionZod2
|
|
892
929
|
} from "@xyo-network/dapp-kit";
|
|
893
930
|
import { asSchema } from "@xyo-network/sdk";
|
|
894
931
|
import { z } from "zod";
|
|
@@ -900,6 +937,15 @@ var ApplicationPortTransportHelloZod = z.strictObject({
|
|
|
900
937
|
maximumFrameBytes: z.number().int().positive().max(16 * 1024 * 1024),
|
|
901
938
|
grant: PortAttachmentGrantZod3
|
|
902
939
|
});
|
|
940
|
+
var ApplicationPortTransportHelloV2Zod = z.strictObject({
|
|
941
|
+
...ApplicationPortTransportHelloZod.shape,
|
|
942
|
+
schemaVersion: z.literal(2),
|
|
943
|
+
frameSchemaVersion: z.literal(2)
|
|
944
|
+
});
|
|
945
|
+
var ApplicationPortTransportHelloAnyVersionZod = z.discriminatedUnion("schemaVersion", [
|
|
946
|
+
ApplicationPortTransportHelloZod,
|
|
947
|
+
ApplicationPortTransportHelloV2Zod
|
|
948
|
+
]);
|
|
903
949
|
var ApplicationPortTransportErrorZod = z.strictObject({
|
|
904
950
|
schema: z.literal(ApplicationPortTransportSchema),
|
|
905
951
|
schemaVersion: z.literal(1),
|
|
@@ -908,8 +954,8 @@ var ApplicationPortTransportErrorZod = z.strictObject({
|
|
|
908
954
|
retriable: z.boolean()
|
|
909
955
|
});
|
|
910
956
|
var ApplicationPortWireMessageZod = z.union([
|
|
911
|
-
|
|
912
|
-
|
|
957
|
+
PortFrameAnyVersionZod2,
|
|
958
|
+
ApplicationPortTransportHelloAnyVersionZod,
|
|
913
959
|
ApplicationPortTransportErrorZod
|
|
914
960
|
]);
|
|
915
961
|
var ApplicationPortWireErrorCode = {
|
|
@@ -981,6 +1027,7 @@ function serializeApplicationPortWireMessage(message, maximumFrameBytes) {
|
|
|
981
1027
|
import {
|
|
982
1028
|
DappEngineSystemReferenceZod,
|
|
983
1029
|
PortAttachmentGrantZod as PortAttachmentGrantZod4,
|
|
1030
|
+
PortFrameSchemaVersionZod as PortFrameSchemaVersionZod3,
|
|
984
1031
|
validateDappEngineSystemReference
|
|
985
1032
|
} from "@xyo-network/dapp-kit";
|
|
986
1033
|
|
|
@@ -1147,6 +1194,7 @@ function operations(bindings, grant, readTarget, admitRecovery) {
|
|
|
1147
1194
|
});
|
|
1148
1195
|
}
|
|
1149
1196
|
async function createDappEngineApplicationPortHost(options) {
|
|
1197
|
+
const frameSchemaVersion = PortFrameSchemaVersionZod3.parse(options.frameSchemaVersion ?? 1);
|
|
1150
1198
|
const reference = DappEngineSystemReferenceZod.parse(options.reference);
|
|
1151
1199
|
const grant = PortAttachmentGrantZod4.parse(options.grant);
|
|
1152
1200
|
const readStatus = options.engine.status.bind(options.engine);
|
|
@@ -1161,6 +1209,7 @@ async function createDappEngineApplicationPortHost(options) {
|
|
|
1161
1209
|
const host = createApplicationPortHost({
|
|
1162
1210
|
authenticatedPrincipalId: options.authenticatedPrincipalId,
|
|
1163
1211
|
endpoint: deferred.endpoint,
|
|
1212
|
+
frameSchemaVersion,
|
|
1164
1213
|
grant,
|
|
1165
1214
|
now: options.now,
|
|
1166
1215
|
onProtocolError: options.onProtocolError,
|
|
@@ -1205,7 +1254,7 @@ async function createDappEngineApplicationPortHost(options) {
|
|
|
1205
1254
|
}
|
|
1206
1255
|
|
|
1207
1256
|
// src/webSocketApplicationPortClient.ts
|
|
1208
|
-
import {
|
|
1257
|
+
import { PortFrameAnyVersionZod as PortFrameAnyVersionZod3, PortFrameSchemaVersionZod as PortFrameSchemaVersionZod4 } from "@xyo-network/dapp-kit";
|
|
1209
1258
|
var WebSocketApplicationPortClientErrorCode = {
|
|
1210
1259
|
aborted: "port.websocket-aborted",
|
|
1211
1260
|
closed: "port.websocket-closed",
|
|
@@ -1294,7 +1343,7 @@ var BrowserWebSocketApplicationPortEndpoint = class {
|
|
|
1294
1343
|
"application-port WebSocket is not open"
|
|
1295
1344
|
);
|
|
1296
1345
|
}
|
|
1297
|
-
const frame =
|
|
1346
|
+
const frame = PortFrameAnyVersionZod3.parse(message);
|
|
1298
1347
|
this.socket.send(serializeApplicationPortWireMessage(frame, this.maximumFrameBytes));
|
|
1299
1348
|
}
|
|
1300
1349
|
receive = (event) => {
|
|
@@ -1325,6 +1374,8 @@ async function connectWebSocketApplicationPort(options) {
|
|
|
1325
1374
|
"application-port connection was aborted before launch"
|
|
1326
1375
|
);
|
|
1327
1376
|
}
|
|
1377
|
+
const acceptedVersions = new Set((options.acceptedFrameSchemaVersions ?? [1, 2]).map((version) => PortFrameSchemaVersionZod4.parse(version)));
|
|
1378
|
+
if (acceptedVersions.size === 0) throw new TypeError("at least one application-port frame schema version must be accepted");
|
|
1328
1379
|
const maximumFrameBytes = positiveInteger(
|
|
1329
1380
|
options.maximumFrameBytes ?? 256 * 1024,
|
|
1330
1381
|
"maximum frame bytes",
|
|
@@ -1375,7 +1426,8 @@ async function connectWebSocketApplicationPort(options) {
|
|
|
1375
1426
|
));
|
|
1376
1427
|
return;
|
|
1377
1428
|
}
|
|
1378
|
-
const parsed =
|
|
1429
|
+
const parsed = ApplicationPortTransportHelloAnyVersionZod.parse(message);
|
|
1430
|
+
if (!acceptedVersions.has(parsed.schemaVersion)) throw new TypeError("server selected an unsupported application-port frame schema version");
|
|
1379
1431
|
assertExpectedGrant(parsed.grant, options.expected, options.now());
|
|
1380
1432
|
cleanup();
|
|
1381
1433
|
resolve(parsed);
|
|
@@ -1409,6 +1461,7 @@ async function connectWebSocketApplicationPort(options) {
|
|
|
1409
1461
|
authenticatedPrincipalId: hello.grant.principalId,
|
|
1410
1462
|
endpoint,
|
|
1411
1463
|
grant: hello.grant,
|
|
1464
|
+
frameSchemaVersion: hello.schemaVersion,
|
|
1412
1465
|
nextRequestId: options.nextRequestId,
|
|
1413
1466
|
now: options.now,
|
|
1414
1467
|
onProtocolError: options.onProtocolError
|
|
@@ -1421,6 +1474,7 @@ async function connectWebSocketApplicationPort(options) {
|
|
|
1421
1474
|
return {
|
|
1422
1475
|
client,
|
|
1423
1476
|
grant: hello.grant,
|
|
1477
|
+
frameSchemaVersion: hello.schemaVersion,
|
|
1424
1478
|
whenClosed: closed.promise,
|
|
1425
1479
|
close: () => {
|
|
1426
1480
|
if (isClosed) return;
|
|
@@ -1441,6 +1495,8 @@ export {
|
|
|
1441
1495
|
ApplicationPortProxyErrorCode,
|
|
1442
1496
|
ApplicationPortRemoteError,
|
|
1443
1497
|
ApplicationPortTransportErrorZod,
|
|
1498
|
+
ApplicationPortTransportHelloAnyVersionZod,
|
|
1499
|
+
ApplicationPortTransportHelloV2Zod,
|
|
1444
1500
|
ApplicationPortTransportHelloZod,
|
|
1445
1501
|
ApplicationPortTransportSchema,
|
|
1446
1502
|
ApplicationPortWireError,
|