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.
@@ -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":"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"}
@@ -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
- function isRecord(value) {
40
- return typeof value === 'object' && value !== null && !Array.isArray(value);
42
+ let runtimeNonceSequence = 0;
43
+ function closedRecordError(code, label, detail) {
44
+ return new ActorAddressingError(code, `${label} ${detail}`);
41
45
  }
42
- function assertExactRecord(value, keys, code, label) {
43
- if (!isRecord(value)) {
44
- throw new ActorAddressingError(code, `${label} must be an object`);
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
- const actualKeys = Object.keys(value).sort();
47
- const expectedKeys = [...keys].sort();
48
- if (actualKeys.length !== expectedKeys.length ||
49
- actualKeys.some((key, index) => key !== expectedKeys[index])) {
50
- throw new ActorAddressingError(code, `${label} must contain only: ${expectedKeys.join(', ')}`);
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
- assertExactRecord(value, ADDRESS_KEYS, 'invalid-address', 'ActorAddress');
74
- if (value.schemaVersion !== ACTOR_ADDRESS_SCHEMA_VERSION) {
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(value.namespace, 'namespace'),
80
- deploymentId: parseAddressSegment(value.deploymentId, 'deploymentId'),
81
- actorKind: parseAddressSegment(value.actorKind, 'actorKind'),
82
- logicalKey: parseAddressSegment(value.logicalKey, 'logicalKey'),
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
- if (!isRecord(value)) {
97
- throw new ActorAddressingError('invalid-selector', 'ActorSelector must be an object');
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 (keys[0] === 'byAddress') {
158
+ if (record.has('byAddress')) {
104
159
  try {
105
- return Object.freeze({ byAddress: parseActorAddress(value.byAddress) });
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(value.byAlias, 'byAlias', 'invalid-selector'),
170
+ byAlias: parseOpaqueToken(record.get('byAlias'), 'byAlias', 'invalid-selector'),
116
171
  });
117
172
  }
118
173
  export function parseActorOwnerSnapshot(value) {
119
- assertExactRecord(value, OWNER_SNAPSHOT_KEYS, 'invalid-owner-snapshot', 'ActorOwnerSnapshot');
120
- if (value.schemaVersion !== ACTOR_OWNER_SNAPSHOT_SCHEMA_VERSION) {
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
- if (!Array.isArray(value.registrations)) {
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 value.registrations) {
129
- assertExactRecord(registration, OWNER_REGISTRATION_KEYS, 'invalid-owner-snapshot', 'owner snapshot registration');
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(registration.address);
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(registration.handlerIdentity, 'handlerIdentity', 'invalid-owner-snapshot'),
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(value.ownerRevision, 'ownerRevision', 'invalid-owner-snapshot'),
153
- snapshotReceipt: parseOpaqueToken(value.snapshotReceipt, 'snapshotReceipt', 'invalid-owner-snapshot'),
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
- assertExactRecord(value, REGISTRATION_RECEIPT_KEYS, 'registration-mismatch', 'ActorRegistrationReceipt');
159
- if (value.schemaVersion !== ACTOR_REGISTRATION_SCHEMA_VERSION) {
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(value.address),
165
- ownerRevision: parseOpaqueToken(value.ownerRevision, 'ownerRevision', 'registration-mismatch'),
166
- snapshotReceipt: parseOpaqueToken(value.snapshotReceipt, 'snapshotReceipt', 'registration-mismatch'),
167
- handlerIdentity: parseOpaqueToken(value.handlerIdentity, 'handlerIdentity', 'registration-mismatch'),
168
- registrationId: parseOpaqueToken(value.registrationId, 'registrationId', 'registration-mismatch'),
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
- if (!isRecord(config) || Object.keys(config).length !== 0) {
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
- export function createLocalActorAddressingRuntime(config = {}) {
184
- if (!isRecord(config)) {
185
- throw new ActorAddressingError('registration-mismatch', 'runtime config must be an object');
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
- const allowedKeys = new Set(['runtimeInstanceId', 'resolveAlias', 'registrationIdFactory']);
188
- if (Object.keys(config).some((key) => !allowedKeys.has(key))) {
189
- throw new ActorAddressingError('registration-mismatch', 'runtime config contains an unsupported field');
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
- if (config.resolveAlias !== undefined && typeof config.resolveAlias !== 'function') {
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 (config.registrationIdFactory !== undefined &&
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(config.runtimeInstanceId ?? `local-runtime-${Date.now().toString(36)}-${randomPart}`, 'runtimeInstanceId', 'registration-mismatch');
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
- registrationIds: new Set(),
204
- resolveAlias: config.resolveAlias,
205
- registrationIdFactory: config.registrationIdFactory ??
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
- assertExactRecord(value, ENDPOINT_KEYS, 'registration-mismatch', 'LocalActorEndpoint');
213
- const handlerIdentity = parseOpaqueToken(value.handlerIdentity, 'handlerIdentity', 'registration-mismatch');
214
- if (typeof value.dispatch !== 'function') {
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: value.dispatch,
288
+ dispatch: dispatch,
220
289
  });
221
290
  }
222
291
  function parseRegisterInput(input) {
223
- assertExactRecord(input, REGISTER_INPUT_KEYS, 'registration-mismatch', 'RegisterActorInput');
292
+ const record = readExactRecord(input, REGISTER_INPUT_KEYS, 'registration-mismatch', 'RegisterActorInput');
224
293
  return {
225
- address: parseActorAddress(input.address),
226
- ownerSnapshot: parseActorOwnerSnapshot(input.ownerSnapshot),
227
- endpoint: parseEndpoint(input.endpoint),
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
- if (!isRecord(value)) {
260
- throw new ActorAddressingError('stale-registration', 'invocation must be an object');
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(value.expectedRegistrationId, 'expectedRegistrationId', 'stale-registration');
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 key = actorAddressKey(parsed.address);
280
- if (state.registrations.has(key)) {
281
- throw new ActorAddressingError('already-registered', `Actor is already registered: ${key}`);
282
- }
283
- const ownerEntry = parsed.ownerSnapshot.registrations.find((entry) => actorAddressKey(entry.address) === key);
284
- if (!ownerEntry || ownerEntry.handlerIdentity !== parsed.endpoint.handlerIdentity) {
285
- throw new ActorAddressingError('registration-mismatch', 'Address and handler identity must be authorized by the owner snapshot');
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
- const sequence = state.sequence + 1;
288
- const registrationId = parseOpaqueToken(state.registrationIdFactory({
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
- if (!isRecord(invocation)) {
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 expectedId = invocation.expectedRegistrationId === undefined
417
+ const expectedRegistrationIdValue = invocationRecord.get('expectedRegistrationId');
418
+ const expectedId = expectedRegistrationIdValue === undefined
334
419
  ? undefined
335
- : parseOpaqueToken(invocation.expectedRegistrationId, 'expectedRegistrationId', 'stale-registration');
420
+ : parseOpaqueToken(expectedRegistrationIdValue, 'expectedRegistrationId', 'stale-registration');
336
421
  assertCurrentRegistration(registration.receipt, expectedId);
337
- return await registration.endpoint.dispatch(invocation.input);
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 registration = resolveRegistration(runtime, selector);
343
- assertCurrentRegistration(registration.receipt, expectedId);
344
- runtimeState(runtime).registrations.delete(actorAddressKey(registration.address));
345
- runtimeState(runtime).registrationIds.delete(registration.receipt.registrationId);
346
- return registration.receipt;
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
- assertExactRecord(config, ['endpointFor'], 'registration-mismatch', 'RebuildActorRegistrationsConfig');
351
- if (typeof config.endpointFor !== 'function') {
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
- if (state.registrations.size !== 0) {
356
- throw new ActorAddressingError('already-registered', 'Registration recovery requires a fresh empty local runtime');
357
- }
358
- const endpoints = snapshot.registrations.map((registration) => {
359
- const endpoint = parseEndpoint(config.endpointFor(registration));
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
- plannedIds.add(registrationId);
378
- const receipt = Object.freeze({
379
- schemaVersion: ACTOR_REGISTRATION_SCHEMA_VERSION,
380
- address: registration.address,
381
- ownerRevision: snapshot.ownerRevision,
382
- snapshotReceipt: snapshot.snapshotReceipt,
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
- return {
387
- key: actorAddressKey(registration.address),
388
- registration: {
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
- receipt,
391
- endpoint: endpoints[index],
392
- },
393
- };
394
- });
395
- for (const item of planned) {
396
- state.registrations.set(item.key, item.registration);
397
- state.registrationIds.add(item.registration.receipt.registrationId);
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');