depa-actor 0.2.1 → 0.2.2
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/addressing.d.ts.map +1 -1
- package/dist/addressing.js +274 -166
- package/dist/addressing.js.map +1 -1
- package/dist-cjs/addressing.cjs +274 -166
- package/package.json +1 -1
- package/src/addressing.ts +415 -195
package/dist/addressing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"addressing.d.ts","sourceRoot":"","sources":["../src/addressing.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"addressing.d.ts","sourceRoot":"","sources":["../src/addressing.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,4BAA4B,EAAG,uBAAgC,CAAC;AAC7E,eAAO,MAAM,mCAAmC,EAAG,8BAAuC,CAAC;AAC3F,eAAO,MAAM,iCAAiC,EAAG,4BAAqC,CAAC;AAEvF,MAAM,MAAM,wBAAwB,GAChC,iBAAiB,GACjB,kBAAkB,GAClB,wBAAwB,GACxB,4BAA4B,GAC5B,oBAAoB,GACpB,qBAAqB,GACrB,uBAAuB,GACvB,oBAAoB,CAAC;AAEzB,qBAAa,oBAAqB,SAAQ,KAAK;IAI3C,QAAQ,CAAC,IAAI,EAAE,wBAAwB;IAHzC,QAAQ,CAAC,IAAI,0BAA0B;gBAG5B,IAAI,EAAE,wBAAwB,EACvC,OAAO,EAAE,MAAM;CAIlB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,aAAa,EAAE,OAAO,4BAA4B,CAAC;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;CAAE,GACpC;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,aAAa,EAAE,OAAO,mCAAmC,CAAC;IACnE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,aAAa,EAAE,SAAS,8BAA8B,EAAE,CAAC;CACnE;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,aAAa,EAAE,OAAO,iCAAiC,CAAC;IACjE,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,kBAAkB,CAAC,WAAW,EAAE,OAAO;IACtD,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,CAAC,UAAU,EAAE,WAAW,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC5E;AAED,OAAO,CAAC,MAAM,gCAAgC,EAAE,OAAO,MAAM,CAAC;AAE9D,MAAM,WAAW,2BAA2B,CAAC,WAAW,EAAE,OAAO;IAC/D,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,CAAC,gCAAgC,CAAC,EAAE;QAC3C,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC;QACjC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,iCAAiC;IAChD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,YAAY,GAAG,SAAS,CAAC;IACpE,QAAQ,CAAC,qBAAqB,CAAC,EAAE,CAAC,KAAK,EAAE;QACvC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;QACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;KAChC,KAAK,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB,CAAC,WAAW,EAAE,OAAO;IACtD,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,kBAAkB,CAAC;IAC3C,QAAQ,CAAC,QAAQ,EAAE,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC7D;AAED,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;AAEnE,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CAC1C;AAED,MAAM,WAAW,uBAAuB,CAAC,WAAW,CAAE,SAAQ,sBAAsB;IAClF,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;CAC7B;AAED,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACzC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,wBAAwB,CAAC;CAC5C;AAED,MAAM,WAAW,+BAA+B,CAAC,WAAW,EAAE,OAAO;IACnE,QAAQ,CAAC,WAAW,EAAE,CACpB,YAAY,EAAE,8BAA8B,KACzC,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;CAC/C;AAED,MAAM,MAAM,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,IAAI,CACrE,OAAO,EAAE,QAAQ,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,OAAO,KACZ,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEhC,MAAM,MAAM,sBAAsB,CAAC,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,IAAI,CACvF,OAAO,EAAE,QAAQ,EACjB,QAAQ,EAAE,SAAS,EACnB,UAAU,EAAE,WAAW,EACvB,MAAM,EAAE,OAAO,KACZ,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAkMhC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY,CAY9D;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAS7D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,aAAa,CA2BhE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAoE1E;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,GAAG,wBAAwB,CAkCtF;AAqDD,wBAAgB,iCAAiC,CAAC,WAAW,EAAE,OAAO,EACpE,MAAM,GAAE,iCAAsC,GAC7C,2BAA2B,CAAC,WAAW,EAAE,OAAO,CAAC,CAwCnD;AAwJD,wBAAgB,aAAa,CAAC,WAAW,EAAE,OAAO,EAChD,OAAO,EAAE,2BAA2B,CAAC,WAAW,EAAE,OAAO,CAAC,EAC1D,KAAK,EAAE,kBAAkB,CAAC,WAAW,EAAE,OAAO,CAAC,EAC/C,MAAM,EAAE,oBAAoB,GAC3B,wBAAwB,CAqD1B;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,OAAO,EAC/C,OAAO,EAAE,2BAA2B,CAAC,WAAW,EAAE,OAAO,CAAC,EAC1D,QAAQ,EAAE,aAAa,EACvB,UAAU,EAAE,sBAAsB,EAClC,MAAM,EAAE,oBAAoB,GAC3B,aAAa,CASf;AAED,wBAAsB,aAAa,CAAC,WAAW,EAAE,OAAO,EACtD,OAAO,EAAE,2BAA2B,CAAC,WAAW,EAAE,OAAO,CAAC,EAC1D,QAAQ,EAAE,aAAa,EACvB,UAAU,EAAE,uBAAuB,CAAC,WAAW,CAAC,EAChD,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,OAAO,EAClD,OAAO,EAAE,2BAA2B,CAAC,WAAW,EAAE,OAAO,CAAC,EAC1D,QAAQ,EAAE,aAAa,EACvB,UAAU,EAAE,yBAAyB,EACrC,MAAM,EAAE,oBAAoB,GAC3B,wBAAwB,CAqB1B;AAED,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,OAAO,EAC5D,OAAO,EAAE,2BAA2B,CAAC,WAAW,EAAE,OAAO,CAAC,EAC1D,KAAK,EAAE,kBAAkB,EACzB,MAAM,EAAE,+BAA+B,CAAC,WAAW,EAAE,OAAO,CAAC,GAC5D,SAAS,wBAAwB,EAAE,CAiGrC;AAED,wBAAgB,sBAAsB,CACpC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvC,IAAI,SAAS,MAAM,OAAO,GAAG,MAAM,EAEnC,GAAG,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAA;CAAE,EACnE,GAAG,EAAE,IAAI,EACT,eAAe,EAAE,MAAM,GACtB,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAUzC"}
|
package/dist/addressing.js
CHANGED
|
@@ -33,22 +33,80 @@ const REGISTRATION_RECEIPT_KEYS = [
|
|
|
33
33
|
];
|
|
34
34
|
const REGISTER_INPUT_KEYS = ['address', 'ownerSnapshot', 'endpoint'];
|
|
35
35
|
const ENDPOINT_KEYS = ['handlerIdentity', 'dispatch'];
|
|
36
|
+
const RUNTIME_CONFIG_KEYS = ['runtimeInstanceId', 'resolveAlias', 'registrationIdFactory'];
|
|
37
|
+
const EXPECTED_REGISTRATION_ID_KEYS = ['expectedRegistrationId'];
|
|
38
|
+
const DISPATCH_INVOCATION_REQUIRED_KEYS = ['input'];
|
|
36
39
|
const ADDRESS_SEGMENT = /^[A-Za-z0-9](?:[A-Za-z0-9._~-]{0,126}[A-Za-z0-9])?$/;
|
|
37
40
|
const OPAQUE_TOKEN = /^[A-Za-z0-9](?:[A-Za-z0-9._~:/-]{0,254}[A-Za-z0-9])?$/;
|
|
38
41
|
const runtimeStates = new WeakMap();
|
|
39
|
-
|
|
40
|
-
|
|
42
|
+
let runtimeNonceSequence = 0;
|
|
43
|
+
function closedRecordError(code, label, detail) {
|
|
44
|
+
return new ActorAddressingError(code, `${label} ${detail}`);
|
|
41
45
|
}
|
|
42
|
-
function
|
|
43
|
-
if (
|
|
44
|
-
throw
|
|
46
|
+
function readClosedRecord(value, requiredKeys, optionalKeys, code, label) {
|
|
47
|
+
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
48
|
+
throw closedRecordError(code, label, 'must be an object');
|
|
49
|
+
}
|
|
50
|
+
const prototype = Reflect.getPrototypeOf(value);
|
|
51
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
52
|
+
throw closedRecordError(code, label, 'must use Object.prototype or a null prototype');
|
|
53
|
+
}
|
|
54
|
+
const allowedKeys = new Set([...requiredKeys, ...optionalKeys]);
|
|
55
|
+
const values = new Map();
|
|
56
|
+
for (const key of Reflect.ownKeys(value)) {
|
|
57
|
+
if (typeof key !== 'string' || !allowedKeys.has(key)) {
|
|
58
|
+
throw closedRecordError(code, label, `must contain only: ${[...allowedKeys].sort().join(', ')}`);
|
|
59
|
+
}
|
|
60
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
61
|
+
if (!descriptor || !descriptor.enumerable || !('value' in descriptor)) {
|
|
62
|
+
throw closedRecordError(code, label, `${key} must be an own enumerable data property`);
|
|
63
|
+
}
|
|
64
|
+
values.set(key, descriptor.value);
|
|
65
|
+
}
|
|
66
|
+
for (const key of requiredKeys) {
|
|
67
|
+
if (!values.has(key)) {
|
|
68
|
+
throw closedRecordError(code, label, `must contain required field: ${key}`);
|
|
69
|
+
}
|
|
45
70
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
71
|
+
return values;
|
|
72
|
+
}
|
|
73
|
+
function readExactRecord(value, keys, code, label) {
|
|
74
|
+
return readClosedRecord(value, keys, [], code, label);
|
|
75
|
+
}
|
|
76
|
+
function readClosedArray(value, code, label) {
|
|
77
|
+
if (!Array.isArray(value) || Reflect.getPrototypeOf(value) !== Array.prototype) {
|
|
78
|
+
throw closedRecordError(code, label, 'must be a plain array');
|
|
79
|
+
}
|
|
80
|
+
const lengthDescriptor = Reflect.getOwnPropertyDescriptor(value, 'length');
|
|
81
|
+
const lengthValue = lengthDescriptor && 'value' in lengthDescriptor ? lengthDescriptor.value : undefined;
|
|
82
|
+
if (!lengthDescriptor ||
|
|
83
|
+
!('value' in lengthDescriptor) ||
|
|
84
|
+
lengthDescriptor.enumerable ||
|
|
85
|
+
typeof lengthValue !== 'number' ||
|
|
86
|
+
!Number.isSafeInteger(lengthValue) ||
|
|
87
|
+
lengthValue < 0) {
|
|
88
|
+
throw closedRecordError(code, label, 'must have the standard own data length property');
|
|
89
|
+
}
|
|
90
|
+
const length = lengthValue;
|
|
91
|
+
const expectedKeys = new Set(['length']);
|
|
92
|
+
for (let index = 0; index < length; index += 1) {
|
|
93
|
+
expectedKeys.add(String(index));
|
|
94
|
+
}
|
|
95
|
+
const ownKeys = Reflect.ownKeys(value);
|
|
96
|
+
if (ownKeys.length !== expectedKeys.size ||
|
|
97
|
+
ownKeys.some((key) => typeof key !== 'string' || !expectedKeys.has(key))) {
|
|
98
|
+
throw closedRecordError(code, label, 'must be dense and contain no extra own keys');
|
|
99
|
+
}
|
|
100
|
+
const elements = [];
|
|
101
|
+
for (let index = 0; index < length; index += 1) {
|
|
102
|
+
const key = String(index);
|
|
103
|
+
const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
|
|
104
|
+
if (!descriptor || !descriptor.enumerable || !('value' in descriptor)) {
|
|
105
|
+
throw closedRecordError(code, label, `${key} must be an own enumerable data property`);
|
|
106
|
+
}
|
|
107
|
+
elements.push(descriptor.value);
|
|
51
108
|
}
|
|
109
|
+
return elements;
|
|
52
110
|
}
|
|
53
111
|
function parseAddressSegment(value, field, code = 'invalid-address') {
|
|
54
112
|
if (typeof value !== 'string' ||
|
|
@@ -70,16 +128,16 @@ function parseOpaqueToken(value, field, code) {
|
|
|
70
128
|
return value;
|
|
71
129
|
}
|
|
72
130
|
export function parseActorAddress(value) {
|
|
73
|
-
|
|
74
|
-
if (
|
|
131
|
+
const record = readExactRecord(value, ADDRESS_KEYS, 'invalid-address', 'ActorAddress');
|
|
132
|
+
if (record.get('schemaVersion') !== ACTOR_ADDRESS_SCHEMA_VERSION) {
|
|
75
133
|
throw new ActorAddressingError('invalid-address', 'Unsupported ActorAddress schemaVersion');
|
|
76
134
|
}
|
|
77
135
|
return Object.freeze({
|
|
78
136
|
schemaVersion: ACTOR_ADDRESS_SCHEMA_VERSION,
|
|
79
|
-
namespace: parseAddressSegment(
|
|
80
|
-
deploymentId: parseAddressSegment(
|
|
81
|
-
actorKind: parseAddressSegment(
|
|
82
|
-
logicalKey: parseAddressSegment(
|
|
137
|
+
namespace: parseAddressSegment(record.get('namespace'), 'namespace'),
|
|
138
|
+
deploymentId: parseAddressSegment(record.get('deploymentId'), 'deploymentId'),
|
|
139
|
+
actorKind: parseAddressSegment(record.get('actorKind'), 'actorKind'),
|
|
140
|
+
logicalKey: parseAddressSegment(record.get('logicalKey'), 'logicalKey'),
|
|
83
141
|
});
|
|
84
142
|
}
|
|
85
143
|
export function actorAddressKey(address) {
|
|
@@ -93,16 +151,13 @@ export function actorAddressKey(address) {
|
|
|
93
151
|
].join(':');
|
|
94
152
|
}
|
|
95
153
|
export function parseActorSelector(value) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
99
|
-
const keys = Object.keys(value);
|
|
100
|
-
if (keys.length !== 1 || (keys[0] !== 'byAddress' && keys[0] !== 'byAlias')) {
|
|
154
|
+
const record = readClosedRecord(value, [], ['byAddress', 'byAlias'], 'invalid-selector', 'ActorSelector');
|
|
155
|
+
if (record.size !== 1) {
|
|
101
156
|
throw new ActorAddressingError('invalid-selector', 'ActorSelector must contain exactly one of byAddress or byAlias');
|
|
102
157
|
}
|
|
103
|
-
if (
|
|
158
|
+
if (record.has('byAddress')) {
|
|
104
159
|
try {
|
|
105
|
-
return Object.freeze({ byAddress: parseActorAddress(
|
|
160
|
+
return Object.freeze({ byAddress: parseActorAddress(record.get('byAddress')) });
|
|
106
161
|
}
|
|
107
162
|
catch (error) {
|
|
108
163
|
if (error instanceof ActorAddressingError) {
|
|
@@ -112,24 +167,22 @@ export function parseActorSelector(value) {
|
|
|
112
167
|
}
|
|
113
168
|
}
|
|
114
169
|
return Object.freeze({
|
|
115
|
-
byAlias: parseOpaqueToken(
|
|
170
|
+
byAlias: parseOpaqueToken(record.get('byAlias'), 'byAlias', 'invalid-selector'),
|
|
116
171
|
});
|
|
117
172
|
}
|
|
118
173
|
export function parseActorOwnerSnapshot(value) {
|
|
119
|
-
|
|
120
|
-
if (
|
|
174
|
+
const record = readExactRecord(value, OWNER_SNAPSHOT_KEYS, 'invalid-owner-snapshot', 'ActorOwnerSnapshot');
|
|
175
|
+
if (record.get('schemaVersion') !== ACTOR_OWNER_SNAPSHOT_SCHEMA_VERSION) {
|
|
121
176
|
throw new ActorAddressingError('invalid-owner-snapshot', 'Unsupported owner snapshot schemaVersion');
|
|
122
177
|
}
|
|
123
|
-
|
|
124
|
-
throw new ActorAddressingError('invalid-owner-snapshot', 'registrations must be an array');
|
|
125
|
-
}
|
|
178
|
+
const sourceRegistrations = readClosedArray(record.get('registrations'), 'invalid-owner-snapshot', 'registrations');
|
|
126
179
|
const registrations = [];
|
|
127
180
|
const seen = new Set();
|
|
128
|
-
for (const registration of
|
|
129
|
-
|
|
181
|
+
for (const registration of sourceRegistrations) {
|
|
182
|
+
const registrationRecord = readExactRecord(registration, OWNER_REGISTRATION_KEYS, 'invalid-owner-snapshot', 'owner snapshot registration');
|
|
130
183
|
let address;
|
|
131
184
|
try {
|
|
132
|
-
address = parseActorAddress(
|
|
185
|
+
address = parseActorAddress(registrationRecord.get('address'));
|
|
133
186
|
}
|
|
134
187
|
catch (error) {
|
|
135
188
|
if (error instanceof ActorAddressingError) {
|
|
@@ -144,34 +197,32 @@ export function parseActorOwnerSnapshot(value) {
|
|
|
144
197
|
seen.add(key);
|
|
145
198
|
registrations.push(Object.freeze({
|
|
146
199
|
address,
|
|
147
|
-
handlerIdentity: parseOpaqueToken(
|
|
200
|
+
handlerIdentity: parseOpaqueToken(registrationRecord.get('handlerIdentity'), 'handlerIdentity', 'invalid-owner-snapshot'),
|
|
148
201
|
}));
|
|
149
202
|
}
|
|
150
203
|
return Object.freeze({
|
|
151
204
|
schemaVersion: ACTOR_OWNER_SNAPSHOT_SCHEMA_VERSION,
|
|
152
|
-
ownerRevision: parseOpaqueToken(
|
|
153
|
-
snapshotReceipt: parseOpaqueToken(
|
|
205
|
+
ownerRevision: parseOpaqueToken(record.get('ownerRevision'), 'ownerRevision', 'invalid-owner-snapshot'),
|
|
206
|
+
snapshotReceipt: parseOpaqueToken(record.get('snapshotReceipt'), 'snapshotReceipt', 'invalid-owner-snapshot'),
|
|
154
207
|
registrations: Object.freeze(registrations),
|
|
155
208
|
});
|
|
156
209
|
}
|
|
157
210
|
export function parseActorRegistrationReceipt(value) {
|
|
158
|
-
|
|
159
|
-
if (
|
|
211
|
+
const record = readExactRecord(value, REGISTRATION_RECEIPT_KEYS, 'registration-mismatch', 'ActorRegistrationReceipt');
|
|
212
|
+
if (record.get('schemaVersion') !== ACTOR_REGISTRATION_SCHEMA_VERSION) {
|
|
160
213
|
throw new ActorAddressingError('registration-mismatch', 'Unsupported registration schemaVersion');
|
|
161
214
|
}
|
|
162
215
|
return Object.freeze({
|
|
163
216
|
schemaVersion: ACTOR_REGISTRATION_SCHEMA_VERSION,
|
|
164
|
-
address: parseActorAddress(
|
|
165
|
-
ownerRevision: parseOpaqueToken(
|
|
166
|
-
snapshotReceipt: parseOpaqueToken(
|
|
167
|
-
handlerIdentity: parseOpaqueToken(
|
|
168
|
-
registrationId: parseOpaqueToken(
|
|
217
|
+
address: parseActorAddress(record.get('address')),
|
|
218
|
+
ownerRevision: parseOpaqueToken(record.get('ownerRevision'), 'ownerRevision', 'registration-mismatch'),
|
|
219
|
+
snapshotReceipt: parseOpaqueToken(record.get('snapshotReceipt'), 'snapshotReceipt', 'registration-mismatch'),
|
|
220
|
+
handlerIdentity: parseOpaqueToken(record.get('handlerIdentity'), 'handlerIdentity', 'registration-mismatch'),
|
|
221
|
+
registrationId: parseOpaqueToken(record.get('registrationId'), 'registrationId', 'registration-mismatch'),
|
|
169
222
|
});
|
|
170
223
|
}
|
|
171
224
|
function assertEmptyConfig(config) {
|
|
172
|
-
|
|
173
|
-
throw new ActorAddressingError('registration-mismatch', 'Processor config must be an empty object');
|
|
174
|
-
}
|
|
225
|
+
readExactRecord(config, [], 'registration-mismatch', 'Processor config');
|
|
175
226
|
}
|
|
176
227
|
function runtimeState(runtime) {
|
|
177
228
|
const state = runtimeStates.get(runtime);
|
|
@@ -180,51 +231,69 @@ function runtimeState(runtime) {
|
|
|
180
231
|
}
|
|
181
232
|
return state;
|
|
182
233
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
234
|
+
function createRuntimeNonce() {
|
|
235
|
+
runtimeNonceSequence += 1;
|
|
236
|
+
const randomPart = typeof globalThis.crypto?.randomUUID === 'function'
|
|
237
|
+
? globalThis.crypto.randomUUID().replaceAll('-', '')
|
|
238
|
+
: `${Date.now().toString(36)}-${Math.random().toString(36).slice(2) || '0'}`;
|
|
239
|
+
return `runtime-${randomPart}-${runtimeNonceSequence.toString(36)}`;
|
|
240
|
+
}
|
|
241
|
+
function beginMutation(state, operation) {
|
|
242
|
+
if (state.mutationGuard !== undefined) {
|
|
243
|
+
throw new ActorAddressingError('registration-mismatch', `${operation} cannot mutate the runtime while ${state.mutationGuard} is in progress`);
|
|
186
244
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
245
|
+
state.mutationGuard = operation;
|
|
246
|
+
return state.mutationVersion;
|
|
247
|
+
}
|
|
248
|
+
function endMutation(state, operation) {
|
|
249
|
+
if (state.mutationGuard === operation) {
|
|
250
|
+
state.mutationGuard = undefined;
|
|
190
251
|
}
|
|
191
|
-
|
|
252
|
+
}
|
|
253
|
+
export function createLocalActorAddressingRuntime(config = {}) {
|
|
254
|
+
const record = readClosedRecord(config, [], RUNTIME_CONFIG_KEYS, 'registration-mismatch', 'runtime config');
|
|
255
|
+
const resolveAlias = record.get('resolveAlias');
|
|
256
|
+
const registrationIdFactory = record.get('registrationIdFactory');
|
|
257
|
+
if (resolveAlias !== undefined && typeof resolveAlias !== 'function') {
|
|
192
258
|
throw new ActorAddressingError('registration-mismatch', 'resolveAlias must be a function');
|
|
193
259
|
}
|
|
194
|
-
if (
|
|
195
|
-
typeof config.registrationIdFactory !== 'function') {
|
|
260
|
+
if (registrationIdFactory !== undefined && typeof registrationIdFactory !== 'function') {
|
|
196
261
|
throw new ActorAddressingError('registration-mismatch', 'registrationIdFactory must be a function');
|
|
197
262
|
}
|
|
198
263
|
const randomPart = Math.random().toString(36).slice(2) || '0';
|
|
199
|
-
const runtimeInstanceId = parseOpaqueToken(
|
|
264
|
+
const runtimeInstanceId = parseOpaqueToken(record.get('runtimeInstanceId') ?? `local-runtime-${Date.now().toString(36)}-${randomPart}`, 'runtimeInstanceId', 'registration-mismatch');
|
|
200
265
|
const runtime = Object.freeze({ runtimeInstanceId });
|
|
201
266
|
runtimeStates.set(runtime, {
|
|
202
267
|
registrations: new Map(),
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
268
|
+
usedRegistrationIds: new Set(),
|
|
269
|
+
runtimeNonce: createRuntimeNonce(),
|
|
270
|
+
resolveAlias: resolveAlias,
|
|
271
|
+
registrationIdFactory: registrationIdFactory ??
|
|
206
272
|
((input) => `${input.runtimeInstanceId}:registration-${input.sequence}`),
|
|
207
273
|
sequence: 0,
|
|
274
|
+
mutationVersion: 0,
|
|
275
|
+
mutationGuard: undefined,
|
|
208
276
|
});
|
|
209
277
|
return runtime;
|
|
210
278
|
}
|
|
211
279
|
function parseEndpoint(value) {
|
|
212
|
-
|
|
213
|
-
const handlerIdentity = parseOpaqueToken(
|
|
214
|
-
|
|
280
|
+
const record = readExactRecord(value, ENDPOINT_KEYS, 'registration-mismatch', 'LocalActorEndpoint');
|
|
281
|
+
const handlerIdentity = parseOpaqueToken(record.get('handlerIdentity'), 'handlerIdentity', 'registration-mismatch');
|
|
282
|
+
const dispatch = record.get('dispatch');
|
|
283
|
+
if (typeof dispatch !== 'function') {
|
|
215
284
|
throw new ActorAddressingError('registration-mismatch', 'endpoint.dispatch must be a function');
|
|
216
285
|
}
|
|
217
286
|
return Object.freeze({
|
|
218
287
|
handlerIdentity,
|
|
219
|
-
dispatch:
|
|
288
|
+
dispatch: dispatch,
|
|
220
289
|
});
|
|
221
290
|
}
|
|
222
291
|
function parseRegisterInput(input) {
|
|
223
|
-
|
|
292
|
+
const record = readExactRecord(input, REGISTER_INPUT_KEYS, 'registration-mismatch', 'RegisterActorInput');
|
|
224
293
|
return {
|
|
225
|
-
address: parseActorAddress(
|
|
226
|
-
ownerSnapshot: parseActorOwnerSnapshot(
|
|
227
|
-
endpoint: parseEndpoint(
|
|
294
|
+
address: parseActorAddress(record.get('address')),
|
|
295
|
+
ownerSnapshot: parseActorOwnerSnapshot(record.get('ownerSnapshot')),
|
|
296
|
+
endpoint: parseEndpoint(record.get('endpoint')),
|
|
228
297
|
};
|
|
229
298
|
}
|
|
230
299
|
function resolveRegistration(runtime, selector) {
|
|
@@ -256,59 +325,80 @@ function resolveRegistration(runtime, selector) {
|
|
|
256
325
|
return registration;
|
|
257
326
|
}
|
|
258
327
|
function expectedRegistrationId(value, required) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
const allowedKeys = required ? ['expectedRegistrationId'] : ['expectedRegistrationId'];
|
|
263
|
-
if (Object.keys(value).some((key) => !allowedKeys.includes(key))) {
|
|
264
|
-
throw new ActorAddressingError('stale-registration', 'invocation contains an unsupported field');
|
|
265
|
-
}
|
|
266
|
-
if (value.expectedRegistrationId === undefined && !required)
|
|
328
|
+
const record = readClosedRecord(value, required ? EXPECTED_REGISTRATION_ID_KEYS : [], required ? [] : EXPECTED_REGISTRATION_ID_KEYS, 'stale-registration', 'invocation');
|
|
329
|
+
const valueToParse = record.get('expectedRegistrationId');
|
|
330
|
+
if (valueToParse === undefined && !required)
|
|
267
331
|
return undefined;
|
|
268
|
-
return parseOpaqueToken(
|
|
332
|
+
return parseOpaqueToken(valueToParse, 'expectedRegistrationId', 'stale-registration');
|
|
269
333
|
}
|
|
270
334
|
function assertCurrentRegistration(registration, expectedId) {
|
|
271
335
|
if (expectedId !== undefined && expectedId !== registration.registrationId) {
|
|
272
336
|
throw new ActorAddressingError('stale-registration', `Expected registration ${expectedId} is not current`);
|
|
273
337
|
}
|
|
274
338
|
}
|
|
339
|
+
function hashRegistrationIdComponent(value) {
|
|
340
|
+
let hash = 0x811c9dc5;
|
|
341
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
342
|
+
hash = Math.imul(hash ^ value.charCodeAt(index), 0x01000193);
|
|
343
|
+
}
|
|
344
|
+
return (hash >>> 0).toString(36);
|
|
345
|
+
}
|
|
346
|
+
function mintRegistrationId(runtime, state, sequence, address, additionallyUsed = new Set()) {
|
|
347
|
+
const factoryValue = parseOpaqueToken(state.registrationIdFactory({
|
|
348
|
+
runtimeInstanceId: runtime.runtimeInstanceId,
|
|
349
|
+
sequence,
|
|
350
|
+
address,
|
|
351
|
+
}), 'registrationIdFactory result', 'registration-mismatch');
|
|
352
|
+
const factoryComponent = factoryValue.length <= 128
|
|
353
|
+
? factoryValue
|
|
354
|
+
: `factory-${hashRegistrationIdComponent(factoryValue)}`;
|
|
355
|
+
const registrationId = parseOpaqueToken(`${factoryComponent}:${state.runtimeNonce}:${sequence.toString(36)}`, 'registrationId', 'registration-mismatch');
|
|
356
|
+
if (state.usedRegistrationIds.has(registrationId) || additionallyUsed.has(registrationId)) {
|
|
357
|
+
throw new ActorAddressingError('registration-mismatch', `registrationIdFactory produced an already-used registration id: ${registrationId}`);
|
|
358
|
+
}
|
|
359
|
+
return registrationId;
|
|
360
|
+
}
|
|
275
361
|
export function registerActor(runtime, input, config) {
|
|
276
362
|
assertEmptyConfig(config);
|
|
277
|
-
const parsed = parseRegisterInput(input);
|
|
278
363
|
const state = runtimeState(runtime);
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
364
|
+
const operation = 'registerActor';
|
|
365
|
+
const startingVersion = beginMutation(state, operation);
|
|
366
|
+
try {
|
|
367
|
+
const parsed = parseRegisterInput(input);
|
|
368
|
+
const key = actorAddressKey(parsed.address);
|
|
369
|
+
if (state.registrations.has(key)) {
|
|
370
|
+
throw new ActorAddressingError('already-registered', `Actor is already registered: ${key}`);
|
|
371
|
+
}
|
|
372
|
+
const ownerEntry = parsed.ownerSnapshot.registrations.find((entry) => actorAddressKey(entry.address) === key);
|
|
373
|
+
if (!ownerEntry || ownerEntry.handlerIdentity !== parsed.endpoint.handlerIdentity) {
|
|
374
|
+
throw new ActorAddressingError('registration-mismatch', 'Address and handler identity must be authorized by the owner snapshot');
|
|
375
|
+
}
|
|
376
|
+
const sequence = state.sequence + 1;
|
|
377
|
+
const registrationId = mintRegistrationId(runtime, state, sequence, parsed.address);
|
|
378
|
+
if (state.mutationVersion !== startingVersion) {
|
|
379
|
+
throw new ActorAddressingError('registration-mismatch', 'Runtime changed while registration was being constructed');
|
|
380
|
+
}
|
|
381
|
+
const receipt = Object.freeze({
|
|
382
|
+
schemaVersion: ACTOR_REGISTRATION_SCHEMA_VERSION,
|
|
383
|
+
address: parsed.address,
|
|
384
|
+
ownerRevision: parsed.ownerSnapshot.ownerRevision,
|
|
385
|
+
snapshotReceipt: parsed.ownerSnapshot.snapshotReceipt,
|
|
386
|
+
handlerIdentity: parsed.endpoint.handlerIdentity,
|
|
387
|
+
registrationId,
|
|
388
|
+
});
|
|
389
|
+
state.sequence = sequence;
|
|
390
|
+
state.registrations.set(key, {
|
|
391
|
+
address: parsed.address,
|
|
392
|
+
receipt,
|
|
393
|
+
endpoint: parsed.endpoint,
|
|
394
|
+
});
|
|
395
|
+
state.usedRegistrationIds.add(registrationId);
|
|
396
|
+
state.mutationVersion = startingVersion + 1;
|
|
397
|
+
return receipt;
|
|
286
398
|
}
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
runtimeInstanceId: runtime.runtimeInstanceId,
|
|
290
|
-
sequence,
|
|
291
|
-
address: parsed.address,
|
|
292
|
-
}), 'registrationId', 'registration-mismatch');
|
|
293
|
-
if (state.registrationIds.has(registrationId)) {
|
|
294
|
-
throw new ActorAddressingError('registration-mismatch', `registrationIdFactory returned a duplicate id: ${registrationId}`);
|
|
399
|
+
finally {
|
|
400
|
+
endMutation(state, operation);
|
|
295
401
|
}
|
|
296
|
-
state.sequence = sequence;
|
|
297
|
-
const receipt = Object.freeze({
|
|
298
|
-
schemaVersion: ACTOR_REGISTRATION_SCHEMA_VERSION,
|
|
299
|
-
address: parsed.address,
|
|
300
|
-
ownerRevision: parsed.ownerSnapshot.ownerRevision,
|
|
301
|
-
snapshotReceipt: parsed.ownerSnapshot.snapshotReceipt,
|
|
302
|
-
handlerIdentity: parsed.endpoint.handlerIdentity,
|
|
303
|
-
registrationId,
|
|
304
|
-
});
|
|
305
|
-
state.registrations.set(key, {
|
|
306
|
-
address: parsed.address,
|
|
307
|
-
receipt,
|
|
308
|
-
endpoint: parsed.endpoint,
|
|
309
|
-
});
|
|
310
|
-
state.registrationIds.add(registrationId);
|
|
311
|
-
return receipt;
|
|
312
402
|
}
|
|
313
403
|
export function resolveActor(runtime, selector, invocation, config) {
|
|
314
404
|
assertEmptyConfig(config);
|
|
@@ -322,82 +412,100 @@ export function resolveActor(runtime, selector, invocation, config) {
|
|
|
322
412
|
}
|
|
323
413
|
export async function dispatchActor(runtime, selector, invocation, config) {
|
|
324
414
|
assertEmptyConfig(config);
|
|
325
|
-
|
|
326
|
-
throw new ActorAddressingError('stale-registration', 'dispatch invocation must be an object');
|
|
327
|
-
}
|
|
328
|
-
const keys = Object.keys(invocation);
|
|
329
|
-
if (!keys.includes('input') || keys.some((key) => key !== 'input' && key !== 'expectedRegistrationId')) {
|
|
330
|
-
throw new ActorAddressingError('stale-registration', 'dispatch invocation must contain input and optional expectedRegistrationId');
|
|
331
|
-
}
|
|
415
|
+
const invocationRecord = readClosedRecord(invocation, DISPATCH_INVOCATION_REQUIRED_KEYS, EXPECTED_REGISTRATION_ID_KEYS, 'stale-registration', 'dispatch invocation');
|
|
332
416
|
const registration = resolveRegistration(runtime, selector);
|
|
333
|
-
const
|
|
417
|
+
const expectedRegistrationIdValue = invocationRecord.get('expectedRegistrationId');
|
|
418
|
+
const expectedId = expectedRegistrationIdValue === undefined
|
|
334
419
|
? undefined
|
|
335
|
-
: parseOpaqueToken(
|
|
420
|
+
: parseOpaqueToken(expectedRegistrationIdValue, 'expectedRegistrationId', 'stale-registration');
|
|
336
421
|
assertCurrentRegistration(registration.receipt, expectedId);
|
|
337
|
-
return await registration.endpoint.dispatch(
|
|
422
|
+
return await registration.endpoint.dispatch(invocationRecord.get('input'));
|
|
338
423
|
}
|
|
339
424
|
export function unregisterActor(runtime, selector, invocation, config) {
|
|
340
425
|
assertEmptyConfig(config);
|
|
341
426
|
const expectedId = expectedRegistrationId(invocation, true);
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
427
|
+
const state = runtimeState(runtime);
|
|
428
|
+
const operation = 'unregisterActor';
|
|
429
|
+
const startingVersion = beginMutation(state, operation);
|
|
430
|
+
try {
|
|
431
|
+
const registration = resolveRegistration(runtime, selector);
|
|
432
|
+
assertCurrentRegistration(registration.receipt, expectedId);
|
|
433
|
+
if (state.mutationVersion !== startingVersion) {
|
|
434
|
+
throw new ActorAddressingError('registration-mismatch', 'Runtime changed while unregister was being resolved');
|
|
435
|
+
}
|
|
436
|
+
state.registrations.delete(actorAddressKey(registration.address));
|
|
437
|
+
state.mutationVersion = startingVersion + 1;
|
|
438
|
+
return registration.receipt;
|
|
439
|
+
}
|
|
440
|
+
finally {
|
|
441
|
+
endMutation(state, operation);
|
|
442
|
+
}
|
|
347
443
|
}
|
|
348
444
|
export function rebuildActorRegistrations(runtime, input, config) {
|
|
349
445
|
const snapshot = parseActorOwnerSnapshot(input);
|
|
350
|
-
|
|
351
|
-
|
|
446
|
+
const configRecord = readExactRecord(config, ['endpointFor'], 'registration-mismatch', 'RebuildActorRegistrationsConfig');
|
|
447
|
+
const endpointFor = configRecord.get('endpointFor');
|
|
448
|
+
if (typeof endpointFor !== 'function') {
|
|
352
449
|
throw new ActorAddressingError('registration-mismatch', 'endpointFor must be a function');
|
|
353
450
|
}
|
|
354
451
|
const state = runtimeState(runtime);
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
if (endpoint.handlerIdentity !== registration.handlerIdentity) {
|
|
361
|
-
throw new ActorAddressingError('registration-mismatch', `Recovered endpoint identity does not match snapshot for ${actorAddressKey(registration.address)}`);
|
|
362
|
-
}
|
|
363
|
-
return endpoint;
|
|
364
|
-
});
|
|
365
|
-
let nextSequence = state.sequence;
|
|
366
|
-
const plannedIds = new Set();
|
|
367
|
-
const planned = snapshot.registrations.map((registration, index) => {
|
|
368
|
-
nextSequence += 1;
|
|
369
|
-
const registrationId = parseOpaqueToken(state.registrationIdFactory({
|
|
370
|
-
runtimeInstanceId: runtime.runtimeInstanceId,
|
|
371
|
-
sequence: nextSequence,
|
|
372
|
-
address: registration.address,
|
|
373
|
-
}), 'registrationId', 'registration-mismatch');
|
|
374
|
-
if (state.registrationIds.has(registrationId) || plannedIds.has(registrationId)) {
|
|
375
|
-
throw new ActorAddressingError('registration-mismatch', `registrationIdFactory returned a duplicate id: ${registrationId}`);
|
|
452
|
+
const operation = 'rebuildActorRegistrations';
|
|
453
|
+
const startingVersion = beginMutation(state, operation);
|
|
454
|
+
try {
|
|
455
|
+
if (state.registrations.size !== 0) {
|
|
456
|
+
throw new ActorAddressingError('already-registered', 'Registration recovery requires a fresh empty local runtime');
|
|
376
457
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
handlerIdentity: registration.handlerIdentity,
|
|
384
|
-
registrationId,
|
|
458
|
+
const endpoints = snapshot.registrations.map((registration) => {
|
|
459
|
+
const endpoint = parseEndpoint(endpointFor(registration));
|
|
460
|
+
if (endpoint.handlerIdentity !== registration.handlerIdentity) {
|
|
461
|
+
throw new ActorAddressingError('registration-mismatch', `Recovered endpoint identity does not match snapshot for ${actorAddressKey(registration.address)}`);
|
|
462
|
+
}
|
|
463
|
+
return endpoint;
|
|
385
464
|
});
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
465
|
+
if (state.mutationVersion !== startingVersion || state.registrations.size !== 0) {
|
|
466
|
+
throw new ActorAddressingError('registration-mismatch', 'Runtime changed while recovery endpoints were being constructed');
|
|
467
|
+
}
|
|
468
|
+
let nextSequence = state.sequence;
|
|
469
|
+
const plannedIds = new Set();
|
|
470
|
+
const planned = snapshot.registrations.map((registration, index) => {
|
|
471
|
+
nextSequence += 1;
|
|
472
|
+
const registrationId = mintRegistrationId(runtime, state, nextSequence, registration.address, plannedIds);
|
|
473
|
+
plannedIds.add(registrationId);
|
|
474
|
+
const receipt = Object.freeze({
|
|
475
|
+
schemaVersion: ACTOR_REGISTRATION_SCHEMA_VERSION,
|
|
389
476
|
address: registration.address,
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
477
|
+
ownerRevision: snapshot.ownerRevision,
|
|
478
|
+
snapshotReceipt: snapshot.snapshotReceipt,
|
|
479
|
+
handlerIdentity: registration.handlerIdentity,
|
|
480
|
+
registrationId,
|
|
481
|
+
});
|
|
482
|
+
return {
|
|
483
|
+
key: actorAddressKey(registration.address),
|
|
484
|
+
registration: {
|
|
485
|
+
address: registration.address,
|
|
486
|
+
receipt,
|
|
487
|
+
endpoint: endpoints[index],
|
|
488
|
+
},
|
|
489
|
+
};
|
|
490
|
+
});
|
|
491
|
+
if (state.mutationVersion !== startingVersion || state.registrations.size !== 0) {
|
|
492
|
+
throw new ActorAddressingError('registration-mismatch', 'Runtime changed while recovery was being planned');
|
|
493
|
+
}
|
|
494
|
+
const nextRegistrations = new Map(planned.map((item) => [item.key, item.registration]));
|
|
495
|
+
const nextUsedRegistrationIds = new Set(state.usedRegistrationIds);
|
|
496
|
+
for (const registrationId of plannedIds) {
|
|
497
|
+
nextUsedRegistrationIds.add(registrationId);
|
|
498
|
+
}
|
|
499
|
+
const receipts = Object.freeze(planned.map((item) => item.registration.receipt));
|
|
500
|
+
state.registrations = nextRegistrations;
|
|
501
|
+
state.usedRegistrationIds = nextUsedRegistrationIds;
|
|
502
|
+
state.sequence = nextSequence;
|
|
503
|
+
state.mutationVersion = startingVersion + 1;
|
|
504
|
+
return receipts;
|
|
505
|
+
}
|
|
506
|
+
finally {
|
|
507
|
+
endMutation(state, operation);
|
|
398
508
|
}
|
|
399
|
-
state.sequence = nextSequence;
|
|
400
|
-
return Object.freeze(planned.map((item) => item.registration.receipt));
|
|
401
509
|
}
|
|
402
510
|
export function createActorRefEndpoint(ref, tag, handlerIdentity) {
|
|
403
511
|
const parsedHandlerIdentity = parseOpaqueToken(handlerIdentity, 'handlerIdentity', 'registration-mismatch');
|