@enbox/dwn-sdk-js 0.0.8 → 0.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.
Files changed (77) hide show
  1. package/dist/browser.mjs +5 -5
  2. package/dist/browser.mjs.map +3 -3
  3. package/dist/esm/generated/precompiled-validators.js +219 -165
  4. package/dist/esm/generated/precompiled-validators.js.map +1 -1
  5. package/dist/esm/src/core/dwn-error.js +3 -0
  6. package/dist/esm/src/core/dwn-error.js.map +1 -1
  7. package/dist/esm/src/core/protocol-authorization-action.js +5 -0
  8. package/dist/esm/src/core/protocol-authorization-action.js.map +1 -1
  9. package/dist/esm/src/core/protocol-authorization-validation.js +24 -0
  10. package/dist/esm/src/core/protocol-authorization-validation.js.map +1 -1
  11. package/dist/esm/src/core/protocol-authorization.js +3 -1
  12. package/dist/esm/src/core/protocol-authorization.js.map +1 -1
  13. package/dist/esm/src/core/resumable-task-manager.js +2 -0
  14. package/dist/esm/src/core/resumable-task-manager.js.map +1 -1
  15. package/dist/esm/src/handlers/records-write.js +81 -0
  16. package/dist/esm/src/handlers/records-write.js.map +1 -1
  17. package/dist/esm/src/interfaces/protocols-configure.js +9 -1
  18. package/dist/esm/src/interfaces/protocols-configure.js.map +1 -1
  19. package/dist/esm/src/interfaces/records-write.js +3 -0
  20. package/dist/esm/src/interfaces/records-write.js.map +1 -1
  21. package/dist/esm/src/store/storage-controller.js +64 -0
  22. package/dist/esm/src/store/storage-controller.js.map +1 -1
  23. package/dist/esm/src/types/protocols-types.js +1 -0
  24. package/dist/esm/src/types/protocols-types.js.map +1 -1
  25. package/dist/esm/tests/features/records-delivery.spec.js +236 -0
  26. package/dist/esm/tests/features/records-delivery.spec.js.map +1 -0
  27. package/dist/esm/tests/features/records-squash.spec.js +1055 -0
  28. package/dist/esm/tests/features/records-squash.spec.js.map +1 -0
  29. package/dist/esm/tests/handlers/records-write.spec.js +3 -0
  30. package/dist/esm/tests/handlers/records-write.spec.js.map +1 -1
  31. package/dist/esm/tests/test-suite.js +4 -0
  32. package/dist/esm/tests/test-suite.js.map +1 -1
  33. package/dist/esm/tests/utils/test-data-generator.js +1 -0
  34. package/dist/esm/tests/utils/test-data-generator.js.map +1 -1
  35. package/dist/types/generated/precompiled-validators.d.ts.map +1 -1
  36. package/dist/types/src/core/dwn-error.d.ts +3 -0
  37. package/dist/types/src/core/dwn-error.d.ts.map +1 -1
  38. package/dist/types/src/core/protocol-authorization-action.d.ts.map +1 -1
  39. package/dist/types/src/core/protocol-authorization-validation.d.ts +9 -0
  40. package/dist/types/src/core/protocol-authorization-validation.d.ts.map +1 -1
  41. package/dist/types/src/core/protocol-authorization.d.ts.map +1 -1
  42. package/dist/types/src/core/resumable-task-manager.d.ts +2 -1
  43. package/dist/types/src/core/resumable-task-manager.d.ts.map +1 -1
  44. package/dist/types/src/handlers/records-write.d.ts +8 -0
  45. package/dist/types/src/handlers/records-write.d.ts.map +1 -1
  46. package/dist/types/src/index.d.ts +1 -1
  47. package/dist/types/src/index.d.ts.map +1 -1
  48. package/dist/types/src/interfaces/protocols-configure.d.ts.map +1 -1
  49. package/dist/types/src/interfaces/records-write.d.ts +6 -0
  50. package/dist/types/src/interfaces/records-write.d.ts.map +1 -1
  51. package/dist/types/src/store/storage-controller.d.ts +16 -2
  52. package/dist/types/src/store/storage-controller.d.ts.map +1 -1
  53. package/dist/types/src/types/protocols-types.d.ts +29 -2
  54. package/dist/types/src/types/protocols-types.d.ts.map +1 -1
  55. package/dist/types/src/types/records-types.d.ts +7 -0
  56. package/dist/types/src/types/records-types.d.ts.map +1 -1
  57. package/dist/types/tests/features/records-delivery.spec.d.ts +2 -0
  58. package/dist/types/tests/features/records-delivery.spec.d.ts.map +1 -0
  59. package/dist/types/tests/features/records-squash.spec.d.ts +2 -0
  60. package/dist/types/tests/features/records-squash.spec.d.ts.map +1 -0
  61. package/dist/types/tests/handlers/records-write.spec.d.ts.map +1 -1
  62. package/dist/types/tests/test-suite.d.ts.map +1 -1
  63. package/dist/types/tests/utils/test-data-generator.d.ts +1 -0
  64. package/dist/types/tests/utils/test-data-generator.d.ts.map +1 -1
  65. package/package.json +3 -3
  66. package/src/core/dwn-error.ts +3 -0
  67. package/src/core/protocol-authorization-action.ts +5 -0
  68. package/src/core/protocol-authorization-validation.ts +37 -0
  69. package/src/core/protocol-authorization.ts +4 -0
  70. package/src/core/resumable-task-manager.ts +3 -1
  71. package/src/handlers/records-write.ts +106 -0
  72. package/src/index.ts +1 -1
  73. package/src/interfaces/protocols-configure.ts +12 -1
  74. package/src/interfaces/records-write.ts +10 -0
  75. package/src/store/storage-controller.ts +78 -1
  76. package/src/types/protocols-types.ts +32 -1
  77. package/src/types/records-types.ts +8 -0
@@ -105,6 +105,7 @@ export type GenerateRecordsWriteInput = {
105
105
  datePublished?: string;
106
106
  encryptionInput?: EncryptionInput;
107
107
  permissionGrantId?: string;
108
+ squash?: true;
108
109
  };
109
110
  export type GenerateFromRecordsWriteInput = {
110
111
  author: Persona;
@@ -1 +1 @@
1
- {"version":3,"file":"test-data-generator.d.ts","sourceRoot":"","sources":["../../../../tests/utils/test-data-generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"test-data-generator.d.ts","sourceRoot":"","sources":["../../../../tests/utils/test-data-generator.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enbox/dwn-sdk-js",
3
- "version": "0.0.8",
3
+ "version": "0.1.0",
4
4
  "description": "A reference implementation of https://identity.foundation/decentralized-web-node/spec/",
5
5
  "repository": {
6
6
  "type": "git",
@@ -64,8 +64,8 @@
64
64
  },
65
65
  "react-native": "./dist/esm/src/index.js",
66
66
  "dependencies": {
67
- "@enbox/crypto": "0.0.5",
68
- "@enbox/dids": "0.0.6",
67
+ "@enbox/crypto": "0.0.6",
68
+ "@enbox/dids": "0.0.7",
69
69
  "@ipld/dag-cbor": "9.0.3",
70
70
  "@js-temporal/polyfill": "0.4.4",
71
71
  "@noble/ciphers": "0.5.3",
@@ -86,6 +86,9 @@ export enum DwnErrorCode {
86
86
  ProtocolAuthorizationMinSizeInvalid = 'ProtocolAuthorizationMinSizeInvalid',
87
87
  ProtocolAuthorizationRecordLimitExceeded = 'ProtocolAuthorizationRecordLimitExceeded',
88
88
  ProtocolAuthorizationRecordLimitStrategyNotImplemented = 'ProtocolAuthorizationRecordLimitStrategyNotImplemented',
89
+ ProtocolAuthorizationSquashNotEnabled = 'ProtocolAuthorizationSquashNotEnabled',
90
+ ProtocolAuthorizationSquashNotInitialWrite = 'ProtocolAuthorizationSquashNotInitialWrite',
91
+ ProtocolAuthorizationSquashBackstop = 'ProtocolAuthorizationSquashBackstop',
89
92
  ProtocolAuthorizationMissingContextId = 'ProtocolAuthorizationMissingContextId',
90
93
  ProtocolAuthorizationMissingRuleSet = 'ProtocolAuthorizationMissingRuleSet',
91
94
  ProtocolAuthorizationParentlessIncorrectProtocolPath = 'ProtocolAuthorizationParentlessIncorrectProtocolPath',
@@ -191,6 +191,11 @@ export async function getActionsSeekingARuleMatch(
191
191
  const incomingRecordsWrite = incomingMessage as RecordsWrite;
192
192
 
193
193
  if (await incomingRecordsWrite.isInitialWrite()) {
194
+ // A squash write seeks the `squash` action first, with fallback to `create`.
195
+ // This means any DID authorized to `create` can also squash when no explicit `squash` rule exists.
196
+ if (incomingRecordsWrite.message.descriptor.squash === true) {
197
+ return [ProtocolAction.Squash, ProtocolAction.Create];
198
+ }
194
199
  return [ProtocolAction.Create];
195
200
  } else {
196
201
  // else incoming RecordsWrite not an initial write
@@ -459,6 +459,43 @@ export async function verifyRecordLimit(
459
459
  }
460
460
  }
461
461
 
462
+ /**
463
+ * Verifies that a `RecordsWrite` with `squash: true` is eligible:
464
+ * 1. The protocol rule set at the record's `protocolPath` must have `$squash: true`.
465
+ * 2. The squash write must be an initial write (a new record, not an update).
466
+ *
467
+ * @throws {DwnError} with `ProtocolAuthorizationSquashNotEnabled` if `$squash` is not enabled.
468
+ * @throws {DwnError} with `ProtocolAuthorizationSquashNotInitialWrite` if the squash write is not an initial write.
469
+ */
470
+ export async function verifySquashEligibility(
471
+ incomingMessage: RecordsWrite,
472
+ ruleSet: ProtocolRuleSet,
473
+ ): Promise<void> {
474
+ const squash = incomingMessage.message.descriptor.squash;
475
+
476
+ if (squash !== true) {
477
+ return;
478
+ }
479
+
480
+ // squash write must be at a protocol path with $squash: true
481
+ if (ruleSet.$squash !== true) {
482
+ throw new DwnError(
483
+ DwnErrorCode.ProtocolAuthorizationSquashNotEnabled,
484
+ `squash writes are not enabled at protocol path '${incomingMessage.message.descriptor.protocolPath}': ` +
485
+ `rule set must have $squash: true.`
486
+ );
487
+ }
488
+
489
+ // squash write must be an initial write (a new record, not an update)
490
+ const isInitialWrite = await incomingMessage.isInitialWrite();
491
+ if (!isInitialWrite) {
492
+ throw new DwnError(
493
+ DwnErrorCode.ProtocolAuthorizationSquashNotInitialWrite,
494
+ `squash write must be an initial write (a new record): updates cannot be squash writes.`
495
+ );
496
+ }
497
+ }
498
+
462
499
  /**
463
500
  * Verifies that an update is not attempted on a record whose protocol path has `$immutable: true`.
464
501
  *
@@ -23,6 +23,7 @@ import {
23
23
  verifyProtocolPathAndContextId,
24
24
  verifyRecordLimit,
25
25
  verifySizeLimit,
26
+ verifySquashEligibility,
26
27
  verifyTagsIfNeeded,
27
28
  verifyTypeWithComposition,
28
29
  } from './protocol-authorization-validation.js';
@@ -105,6 +106,9 @@ export class ProtocolAuthorization {
105
106
  // Verify immutability — reject updates to write-once records
106
107
  await verifyImmutability(incomingMessage, ruleSet);
107
108
 
109
+ // Verify squash eligibility — ensure squash writes are at $squash: true paths and are initial writes
110
+ await verifySquashEligibility(incomingMessage, ruleSet);
111
+
108
112
  // Verify record count limit
109
113
  await verifyRecordLimit(tenant, incomingMessage, ruleSet, messageStore);
110
114
  }
@@ -3,6 +3,7 @@ import type { ManagedResumableTask, ResumableTaskStore } from '../types/resumabl
3
3
 
4
4
  export enum ResumableTaskName {
5
5
  RecordsDelete = 'RecordsDelete',
6
+ RecordsSquash = 'RecordsSquash',
6
7
  }
7
8
 
8
9
  export type ResumableTask = {
@@ -26,7 +27,8 @@ export class ResumableTaskManager {
26
27
  this.resumableTaskHandlers = {
27
28
  // NOTE: The arrow function is IMPORTANT here, else the `this` context will be lost within the invoked method.
28
29
  // e.g. code within performRecordsDelete() won't know `this` refers to the `storageController` instance.
29
- [ResumableTaskName.RecordsDelete]: async (task): Promise<void> => await storageController.performRecordsDelete(task),
30
+ [ResumableTaskName.RecordsDelete] : async (task): Promise<void> => await storageController.performRecordsDelete(task),
31
+ [ResumableTaskName.RecordsSquash] : async (task): Promise<void> => await storageController.performRecordsSquash(task),
30
32
  };
31
33
  }
32
34
 
@@ -1,3 +1,4 @@
1
+ import type { Filter } from '../types/query-types.js';
1
2
  import type { GenericMessageReply } from '../types/message-types.js';
2
3
  import type { MessageStore } from '../types/message-store.js';
3
4
  import type { HandlerDependencies, MethodHandler } from '../types/method-handler.js';
@@ -8,12 +9,16 @@ import { Cid } from '../utils/cid.js';
8
9
  import { DataStream } from '../utils/data-stream.js';
9
10
  import { DwnConstant } from '../core/dwn-constant.js';
10
11
  import { Encoder } from '../utils/encoder.js';
12
+ import { FilterUtility } from '../utils/filter.js';
11
13
  import { Message } from '../core/message.js';
12
14
  import { messageReplyFromError } from '../core/message-reply.js';
13
15
  import { PermissionsProtocol } from '../protocols/permissions.js';
14
16
  import { ProtocolAuthorization } from '../core/protocol-authorization.js';
17
+ import { Records } from '../utils/records.js';
15
18
  import { RecordsGrantAuthorization } from '../core/records-grant-authorization.js';
16
19
  import { RecordsWrite } from '../interfaces/records-write.js';
20
+ import { ResumableTaskName } from '../core/resumable-task-manager.js';
21
+ import { SortDirection } from '../types/query-types.js';
17
22
  import { StorageController } from '../store/storage-controller.js';
18
23
  import { DwnError, DwnErrorCode } from '../core/dwn-error.js';
19
24
  import { DwnInterfaceName, DwnMethodName } from '../enums/dwn-interface-method.js';
@@ -65,6 +70,15 @@ export class RecordsWriteHandler implements MethodHandler {
65
70
  }
66
71
  }
67
72
 
73
+ // Squash backstop: if the protocol path has $squash: true, reject any write whose
74
+ // messageTimestamp is <= the most recent squash record at the same path and parent context.
75
+ // The squash record acts as a temporal floor — no record older than the latest squash can exist.
76
+ try {
77
+ await this.enforceSquashBackstop(tenant, message);
78
+ } catch (e) {
79
+ return messageReplyFromError(e, 409);
80
+ }
81
+
68
82
  const newestExistingMessage = await Message.getNewestMessage(existingMessages);
69
83
 
70
84
  let incomingMessageIsNewest = false;
@@ -167,6 +181,15 @@ export class RecordsWriteHandler implements MethodHandler {
167
181
  tenant, existingMessages, newestMessage, this.deps.messageStore, this.deps.dataStore!, this.deps.stateIndex!
168
182
  );
169
183
 
184
+ // Squash processing: if the incoming write is a squash, delete all older sibling records
185
+ // at the same protocol path and parent context. Uses the resumable task system for crash safety.
186
+ if (message.descriptor.squash === true) {
187
+ await this.deps.resumableTaskManager!.run({
188
+ name : ResumableTaskName.RecordsSquash,
189
+ data : { tenant, message }
190
+ });
191
+ }
192
+
170
193
  // Dispatch post-processing hooks to the core protocol, if applicable.
171
194
  // This allows core protocols to perform cascading side effects after a successful write
172
195
  // (e.g. deleting messages authorized by a revoked grant).
@@ -306,6 +329,89 @@ export class RecordsWriteHandler implements MethodHandler {
306
329
  }
307
330
  }
308
331
 
332
+ /**
333
+ * Enforces the squash backstop: if the incoming message is at a protocol path with `$squash: true`,
334
+ * and there exists a squash record at the same protocol path and parent context whose
335
+ * `messageTimestamp` is >= the incoming message's `messageTimestamp`, reject with 409.
336
+ *
337
+ * This check only applies to protocol-based records at `$squash: true` paths.
338
+ */
339
+ private async enforceSquashBackstop(tenant: string, message: RecordsWriteMessage): Promise<void> {
340
+ // Only applies to protocol-based records
341
+ if (message.descriptor.protocol === undefined || message.descriptor.protocolPath === undefined) {
342
+ return;
343
+ }
344
+
345
+ // Fetch the protocol definition to check if $squash is enabled at this path.
346
+ // Pass coreProtocols so that core protocols (e.g. permissions) are resolved from the registry.
347
+ let protocolDefinition;
348
+ try {
349
+ protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
350
+ tenant,
351
+ message.descriptor.protocol,
352
+ this.deps.messageStore,
353
+ undefined,
354
+ this.deps.coreProtocols,
355
+ );
356
+ } catch (error) {
357
+ // If the protocol definition can't be found, skip the backstop check.
358
+ // Authorization will handle the missing protocol error later.
359
+ console.warn(`enforceSquashBackstop: failed to fetch protocol definition for '${message.descriptor.protocol}':`, error);
360
+ return;
361
+ }
362
+
363
+ // Walk the structure to find the rule set for this protocol path
364
+ const pathSegments = message.descriptor.protocolPath.split('/');
365
+ let ruleSet = protocolDefinition.structure[pathSegments[0]];
366
+ for (let i = 1; i < pathSegments.length && ruleSet !== undefined; i++) {
367
+ ruleSet = ruleSet[pathSegments[i]] as typeof ruleSet;
368
+ }
369
+
370
+ if (ruleSet === undefined || ruleSet.$squash !== true) {
371
+ return;
372
+ }
373
+
374
+ // Find the most recent squash record at the same protocol path and parent context
375
+ const filter: Filter = {
376
+ interface : DwnInterfaceName.Records,
377
+ method : DwnMethodName.Write,
378
+ isLatestBaseState : true,
379
+ protocol : message.descriptor.protocol,
380
+ protocolPath : message.descriptor.protocolPath,
381
+ squash : true,
382
+ };
383
+
384
+ // Scope by parent context for nested records
385
+ const parentContextId = Records.getParentContextFromOfContextId(message.contextId);
386
+ if (parentContextId !== undefined && parentContextId !== '') {
387
+ const prefixFilter = FilterUtility.constructPrefixFilterAsRangeFilter(parentContextId);
388
+ filter.contextId = prefixFilter;
389
+ }
390
+
391
+ const { messages: squashMessages } = await this.deps.messageStore.query(
392
+ tenant,
393
+ [filter],
394
+ { messageTimestamp: SortDirection.Descending },
395
+ { limit: 1 },
396
+ );
397
+
398
+ if (squashMessages.length === 0) {
399
+ return;
400
+ }
401
+
402
+ const newestSquash = squashMessages[0] as RecordsWriteMessage;
403
+
404
+ // Reject if the incoming message's timestamp is <= the squash record's timestamp
405
+ if (message.descriptor.messageTimestamp <= newestSquash.descriptor.messageTimestamp) {
406
+ throw new DwnError(
407
+ DwnErrorCode.ProtocolAuthorizationSquashBackstop,
408
+ `incoming message timestamp '${message.descriptor.messageTimestamp}' is not newer than ` +
409
+ `the most recent squash record timestamp '${newestSquash.descriptor.messageTimestamp}' ` +
410
+ `at protocol path '${message.descriptor.protocolPath}'.`
411
+ );
412
+ }
413
+ }
414
+
309
415
  private async authorizeRecordsWrite(tenant: string, recordsWrite: RecordsWrite, messageStore: MessageStore): Promise<void> {
310
416
  // if owner signature is given (`owner` is not `undefined`), it must be the same as the tenant DID
311
417
  if (recordsWrite.owner !== undefined && recordsWrite.owner !== tenant) {
package/src/index.ts CHANGED
@@ -4,7 +4,7 @@ export type { EventListener, EventLog, EventLogEntry, EventLogReadOptions, Event
4
4
  export type { AuthorizationModel, Descriptor, DelegatedGrantRecordsWriteMessage, GenericMessage, GenericMessageReply, GenericSignaturePayload, MessageSort, MessageSubscription, Pagination, QueryResultEntry, Status } from './types/message-types.js';
5
5
  export type { MessagesFilter, MessagesReadMessage as MessagesReadMessage, MessagesReadReply as MessagesReadReply, MessagesReadReplyEntry as MessagesReadReplyEntry, MessagesReadDescriptor, MessagesSubscribeDescriptor, MessagesSubscribeMessage, MessagesSubscribeReply, MessageSubscriptionHandler, MessagesSubscribeMessageOptions, MessagesSyncAction, MessagesSyncDescriptor, MessagesSyncMessage, MessagesSyncReply } from './types/messages-types.js';
6
6
  export type { GT, LT, Filter, FilterValue, KeyValues, EqualFilter, OneOfFilter, RangeFilter, RangeCriterion, PaginationCursor, QueryOptions, RangeValue, StartsWithFilter } from './types/query-types.js';
7
- export type { ProtocolsConfigureDescriptor, ProtocolDefinition, ProtocolTypes, ProtocolRuleSet, ProtocolsQueryFilter, ProtocolsConfigureMessage, ProtocolsQueryMessage, ProtocolsQueryReply, ProtocolActionRule, ProtocolPathEncryption, ProtocolsQueryDescriptor, ProtocolRecordLimitDefinition, ProtocolSizeDefinition, ProtocolTagsDefinition, ProtocolTagSchema, ProtocolType, ProtocolUses } from './types/protocols-types.js';
7
+ export type { ProtocolsConfigureDescriptor, ProtocolDefinition, ProtocolTypes, ProtocolRuleSet, ProtocolsQueryFilter, ProtocolsConfigureMessage, ProtocolsQueryMessage, ProtocolsQueryReply, ProtocolActionRule, ProtocolDeliveryStrategy, ProtocolPathEncryption, ProtocolsQueryDescriptor, ProtocolRecordLimitDefinition, ProtocolSizeDefinition, ProtocolTagsDefinition, ProtocolTagSchema, ProtocolType, ProtocolUses } from './types/protocols-types.js';
8
8
  export { ProtocolRecordLimitStrategy } from './types/protocols-types.js';
9
9
  export type { DataEncodedRecordsWriteMessage, RecordsCountDescriptor, RecordsCountMessage, RecordsCountReply, RecordsDeleteMessage, RecordsFilter, RecordsQueryMessage, RecordsQueryReply, RecordsQueryReplyEntry, RecordsReadMessage, RecordsReadReply, RecordsSubscribeDescriptor, RecordsSubscribeMessage, RecordsSubscribeReply, RecordSubscriptionHandler, RecordsWriteDescriptor, RecordsWriteTags, RecordsWriteTagValue, RecordsWriteMessage, RecordsWriteSignaturePayload, RecordsDeleteDescriptor, RecordsQueryDescriptor, RecordsReadDescriptor, RecordsSubscribeMessageOptions, RecordsWriteMessageOptions, InternalRecordsWriteMessage, RecordEvent, RecordsWriteTagsFilter } from './types/records-types.js';
10
10
  export type { GeneralJws, SignatureEntry } from './types/jws-types.js';
@@ -418,6 +418,17 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
418
418
  }
419
419
  }
420
420
 
421
+ // Warn when `$delivery` is set without `$actions`.
422
+ // Delivery targets are determined from `$actions` role records and actor rules.
423
+ // Without `$actions`, the server cannot determine who to deliver records to.
424
+ if (ruleSet.$delivery !== undefined && (ruleSet.$actions === undefined || ruleSet.$actions.length === 0)) {
425
+ console.warn(
426
+ `ProtocolsConfigure: protocol path '${ruleSetProtocolPath}' has $delivery: '${ruleSet.$delivery}' ` +
427
+ `but no $actions rules. The server uses $actions to determine delivery targets — ` +
428
+ `without $actions, no participants can be resolved for delivery.`
429
+ );
430
+ }
431
+
421
432
  // Warn when `$immutable: true` is combined with `$actions` that include `update` or `co-update`.
422
433
  // The `$immutable` directive overrides any update permission — updates are always rejected.
423
434
  if (ruleSet.$immutable === true && actionRules.length > 0) {
@@ -494,7 +505,7 @@ export class ProtocolsConfigure extends AbstractMessage<ProtocolsConfigureMessag
494
505
  }
495
506
 
496
507
  // validate that `$ref` nodes do not have other directives
497
- const forbiddenDirectives = ['$actions', '$role', '$size', '$tags', '$encryption', '$recordLimit', '$immutable'] as const;
508
+ const forbiddenDirectives = ['$actions', '$role', '$size', '$tags', '$encryption', '$recordLimit', '$immutable', '$delivery', '$squash'] as const;
498
509
  for (const directive of forbiddenDirectives) {
499
510
  if (ruleSet[directive] !== undefined) {
500
511
  throw new DwnError(
@@ -79,6 +79,13 @@ export type RecordsWriteOptions = {
79
79
  encryptionInput?: EncryptionInput;
80
80
  permissionGrantId?: string;
81
81
 
82
+ /**
83
+ * When `true`, this record is a squash (snapshot) write that atomically creates a snapshot
84
+ * and deletes all older sibling records at the same protocol path within the same parent context.
85
+ * Only valid at protocol paths with `$squash: true`. Must be an initial write (new record).
86
+ */
87
+ squash?: true;
88
+
82
89
  /**
83
90
  * The author's ProtocolPath-derived public key for key delivery.
84
91
  * When set, this is attached to the authorization model so the DWN owner
@@ -325,6 +332,7 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
325
332
  datePublished : options.datePublished,
326
333
  dataFormat : options.dataFormat,
327
334
  permissionGrantId : options.permissionGrantId,
335
+ squash : options.squash,
328
336
  };
329
337
 
330
338
  // generate `datePublished` if the message is to be published but `datePublished` is not given
@@ -742,11 +750,13 @@ export class RecordsWrite implements MessageInterface<RecordsWriteMessage> {
742
750
  // we want to process tags separately from the rest of descriptors as it is an object and not a primitive KeyValue type.
743
751
  const { tags, ...descriptor } = message.descriptor;
744
752
  delete descriptor.published; // handle `published` specifically further down
753
+ delete descriptor.squash; // handle `squash` specifically further down
745
754
 
746
755
  let indexes: KeyValues = {
747
756
  ...descriptor,
748
757
  isLatestBaseState,
749
758
  published : !!message.descriptor.published,
759
+ squash : !!message.descriptor.squash,
750
760
  author : this.author!, //author will not be undefined when indexes are constructed as it's been authorized
751
761
  recordId : message.recordId,
752
762
  entryId : await RecordsWrite.getEntryId(this.author, this.message.descriptor)
@@ -1,11 +1,13 @@
1
1
  import type { DataStore } from '../types/data-store.js';
2
2
  import type { EventLog } from '../types/subscriptions.js';
3
+ import type { Filter } from '../types/query-types.js';
3
4
  import type { GenericMessage } from '../types/message-types.js';
4
5
  import type { MessageStore } from '../types/message-store.js';
5
6
  import type { StateIndex } from '../types/state-index.js';
6
7
  import type { RecordsDeleteMessage, RecordsQueryReplyEntry, RecordsWriteMessage } from '../types/records-types.js';
7
8
 
8
9
  import { DwnConstant } from '../core/dwn-constant.js';
10
+ import { FilterUtility } from '../utils/filter.js';
9
11
  import { Message } from '../core/message.js';
10
12
  import { Records } from '../utils/records.js';
11
13
  import { RecordsDelete } from '../interfaces/records-delete.js';
@@ -18,6 +20,11 @@ export type ResumableRecordsDeleteData = {
18
20
  message: RecordsDeleteMessage;
19
21
  };
20
22
 
23
+ export type ResumableRecordsSquashData = {
24
+ tenant: string;
25
+ message: RecordsWriteMessage;
26
+ };
27
+
21
28
  /**
22
29
  * A class that provides an abstraction for the usage of MessageStore, DataStore, and StateIndex.
23
30
  */
@@ -82,6 +89,76 @@ export class StorageController {
82
89
  );
83
90
  }
84
91
 
92
+ /**
93
+ * Performs the squash processing for a `RecordsWrite` with `squash: true`.
94
+ * Deletes all sibling records at the same protocol path and parent context whose
95
+ * `messageTimestamp` is strictly older than the squash record's `messageTimestamp`.
96
+ * Unlike normal `RecordsDelete` tombstones, squash targets are fully purged — no initial writes
97
+ * are retained.
98
+ *
99
+ * This method is idempotent — it can be safely re-run on resume after a crash.
100
+ */
101
+ public async performRecordsSquash({ tenant, message }: ResumableRecordsSquashData): Promise<void> {
102
+ const { protocol, protocolPath, messageTimestamp } = message.descriptor;
103
+
104
+ // Build a filter to find all sibling records at the same protocol path and parent context.
105
+ // We query by interface only (not method) so that both RecordsWrite and RecordsDelete messages are found.
106
+ const filter: Filter = {
107
+ interface : DwnInterfaceName.Records,
108
+ protocol,
109
+ protocolPath : protocolPath,
110
+ };
111
+
112
+ // Scope by parent context for nested records
113
+ const parentContextId = Records.getParentContextFromOfContextId(message.contextId);
114
+ if (parentContextId !== undefined && parentContextId !== '') {
115
+ const prefixFilter = FilterUtility.constructPrefixFilterAsRangeFilter(parentContextId);
116
+ filter.contextId = prefixFilter;
117
+ }
118
+
119
+ // Query for all records at this path and context
120
+ const { messages: siblingMessages } = await this.messageStore.query(tenant, [filter]);
121
+
122
+ // Group messages by recordId — RecordsWrite messages use `message.recordId`,
123
+ // RecordsDelete messages use `message.descriptor.recordId`.
124
+ const recordIdToMessages = new Map<string, GenericMessage[]>();
125
+ for (const msg of siblingMessages) {
126
+ let recordId: string;
127
+ if (Records.isRecordsWrite(msg)) {
128
+ recordId = msg.recordId;
129
+ } else {
130
+ recordId = (msg as RecordsDeleteMessage).descriptor.recordId;
131
+ }
132
+
133
+ const existing = recordIdToMessages.get(recordId);
134
+ if (existing !== undefined) {
135
+ existing.push(msg);
136
+ } else {
137
+ recordIdToMessages.set(recordId, [msg]);
138
+ }
139
+ }
140
+
141
+ // Delete all records whose newest message timestamp is strictly older than the squash timestamp.
142
+ // Skip the squash record itself.
143
+ for (const [recordId, messages] of recordIdToMessages) {
144
+ if (recordId === message.recordId) {
145
+ continue;
146
+ }
147
+
148
+ // Use the newest message's timestamp to determine if the record predates the squash.
149
+ const newestMessage = await Message.getNewestMessage(messages);
150
+ if (newestMessage === undefined) {
151
+ continue;
152
+ }
153
+
154
+ const newestTimestamp = newestMessage.descriptor.messageTimestamp;
155
+ if (newestTimestamp < messageTimestamp) {
156
+ // Fully purge this record — all messages (including initial write) and their data
157
+ await StorageController.purgeRecordMessages(tenant, messages, this.messageStore, this.dataStore, this.stateIndex);
158
+ }
159
+ }
160
+ }
161
+
85
162
  /**
86
163
  * Deletes the data referenced by the given message if needed.
87
164
  * @param message The message to check if the data it references should be deleted.
@@ -164,7 +241,7 @@ export class StorageController {
164
241
  * Purges (permanent hard-delete) all messages of the SAME `recordId` given and their associated data and events.
165
242
  * Assumes that the given `recordMessages` are all of the same `recordId`.
166
243
  */
167
- private static async purgeRecordMessages(
244
+ public static async purgeRecordMessages(
168
245
  tenant: string,
169
246
  recordMessages: GenericMessage[],
170
247
  messageStore: MessageStore,
@@ -75,6 +75,7 @@ export enum ProtocolAction {
75
75
  Delete = 'delete',
76
76
  Prune = 'prune',
77
77
  Read = 'read',
78
+ Squash = 'squash',
78
79
  Update = 'update'
79
80
  }
80
81
 
@@ -184,6 +185,17 @@ export type ProtocolRecordLimitDefinition = {
184
185
  strategy: ProtocolRecordLimitStrategy | `${ProtocolRecordLimitStrategy}` | (string & {});
185
186
  };
186
187
 
188
+ /**
189
+ * Delivery strategy for records at a given protocol path.
190
+ * Controls how a DWN server proactively distributes records to participants' DWN endpoints.
191
+ *
192
+ * - `'direct'` — The origin DWN pushes new records to all participants' DWN endpoints.
193
+ * Best for small participant sets (2–50).
194
+ * - `'subscribe'` — Participant providers establish `RecordsSubscribe` connections to the
195
+ * origin DWN. Best for asymmetric fan-out or unbounded audiences.
196
+ */
197
+ export type ProtocolDeliveryStrategy = 'direct' | 'subscribe';
198
+
187
199
  /**
188
200
  * Tag rules for records at a given protocol path. Each non-`$`-prefixed property
189
201
  * is a JSON Schema object constraining that tag's value.
@@ -222,7 +234,7 @@ export type ProtocolTagSchema = {
222
234
  /**
223
235
  * Union of all value types that can appear as properties of a `ProtocolRuleSet`.
224
236
  * This includes:
225
- * - `$`-prefixed directive values (`$encryption`, `$actions`, `$role`, `$ref`, `$size`, `$tags`)
237
+ * - `$`-prefixed directive values (`$encryption`, `$actions`, `$role`, `$ref`, `$size`, `$tags`, `$delivery`)
226
238
  * - Child `ProtocolRuleSet` entries (non-`$` keys)
227
239
  */
228
240
  type ProtocolRuleSetValue =
@@ -232,6 +244,7 @@ type ProtocolRuleSetValue =
232
244
  | ProtocolTagsDefinition
233
245
  | ProtocolSizeDefinition
234
246
  | ProtocolRecordLimitDefinition
247
+ | ProtocolDeliveryStrategy
235
248
  | boolean
236
249
  | string
237
250
  | undefined;
@@ -293,6 +306,24 @@ export type ProtocolRuleSet = {
293
306
  */
294
307
  $immutable?: boolean;
295
308
 
309
+ /**
310
+ * Delivery strategy hint for records at this protocol path.
311
+ * When set, the DWN server SHOULD proactively deliver records to participants' DWN endpoints.
312
+ *
313
+ * - `'direct'` — Origin DWN pushes to all participant DWN endpoints upon receipt.
314
+ * - `'subscribe'` — Participant providers subscribe to the origin DWN via `RecordsSubscribe`.
315
+ */
316
+ $delivery?: ProtocolDeliveryStrategy;
317
+
318
+ /**
319
+ * If `$squash` is `true`, enables squash writes at this protocol path.
320
+ * A squash write is a `RecordsWrite` with `squash: true` in the descriptor that
321
+ * atomically creates a new record (the snapshot) and deletes all sibling records
322
+ * at the same protocol path within the same parent context that have a
323
+ * `messageTimestamp` strictly older than the squash record's `messageTimestamp`.
324
+ */
325
+ $squash?: boolean;
326
+
296
327
  /**
297
328
  * Non-`$`-prefixed keys are nested child `ProtocolRuleSet` entries.
298
329
  * At runtime, JSON Schema validation ensures only valid child rule sets appear here.
@@ -38,6 +38,14 @@ export type RecordsWriteDescriptor = {
38
38
  datePublished?: string;
39
39
  dataFormat: string;
40
40
  permissionGrantId?: string;
41
+
42
+ /**
43
+ * When `true`, this record is a squash (snapshot) write. The protocol rule set at this record's
44
+ * `protocolPath` must have `$squash: true`; otherwise the message is rejected.
45
+ * A squash write must be an initial write (a new record, not an update).
46
+ * This is an immutable property.
47
+ */
48
+ squash?: true;
41
49
  };
42
50
 
43
51
  export type RecordsWriteMessageOptions = {