@haverstack/core 0.43.0 → 0.45.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 (108) hide show
  1. package/README.md +1 -2
  2. package/dist/access.d.ts +7 -3
  3. package/dist/access.d.ts.map +1 -1
  4. package/dist/access.js +11 -2
  5. package/dist/access.js.map +1 -1
  6. package/dist/adapter/blobs.d.ts +18 -0
  7. package/dist/adapter/blobs.d.ts.map +1 -0
  8. package/dist/adapter/blobs.js +27 -0
  9. package/dist/adapter/blobs.js.map +1 -0
  10. package/dist/adapter/combine.d.ts.map +1 -1
  11. package/dist/adapter/combine.js +15 -8
  12. package/dist/adapter/combine.js.map +1 -1
  13. package/dist/adapter/copy.d.ts +31 -0
  14. package/dist/adapter/copy.d.ts.map +1 -0
  15. package/dist/adapter/copy.js +131 -0
  16. package/dist/adapter/copy.js.map +1 -0
  17. package/dist/adapter/head.d.ts +38 -0
  18. package/dist/adapter/head.d.ts.map +1 -0
  19. package/dist/adapter/head.js +85 -0
  20. package/dist/adapter/head.js.map +1 -0
  21. package/dist/adapter/index.d.ts +9 -2
  22. package/dist/adapter/index.d.ts.map +1 -1
  23. package/dist/adapter/index.js +6 -1
  24. package/dist/adapter/index.js.map +1 -1
  25. package/dist/adapter/seed.d.ts +13 -0
  26. package/dist/adapter/seed.d.ts.map +1 -0
  27. package/dist/adapter/seed.js +26 -0
  28. package/dist/adapter/seed.js.map +1 -0
  29. package/dist/errors.d.ts +18 -4
  30. package/dist/errors.d.ts.map +1 -1
  31. package/dist/errors.js +28 -6
  32. package/dist/errors.js.map +1 -1
  33. package/dist/grants.d.ts +16 -4
  34. package/dist/grants.d.ts.map +1 -1
  35. package/dist/grants.js +44 -16
  36. package/dist/grants.js.map +1 -1
  37. package/dist/hash.d.ts +8 -0
  38. package/dist/hash.d.ts.map +1 -0
  39. package/dist/hash.js +14 -0
  40. package/dist/hash.js.map +1 -0
  41. package/dist/index.d.ts +1 -1
  42. package/dist/index.d.ts.map +1 -1
  43. package/dist/index.js.map +1 -1
  44. package/dist/install.d.ts +29 -5
  45. package/dist/install.d.ts.map +1 -1
  46. package/dist/install.js +69 -44
  47. package/dist/install.js.map +1 -1
  48. package/dist/schema.d.ts.map +1 -1
  49. package/dist/schema.js +2 -5
  50. package/dist/schema.js.map +1 -1
  51. package/dist/scoped-stack/authority.d.ts +19 -14
  52. package/dist/scoped-stack/authority.d.ts.map +1 -1
  53. package/dist/scoped-stack/authority.js +30 -18
  54. package/dist/scoped-stack/authority.js.map +1 -1
  55. package/dist/scoped-stack/family-policy.js +1 -1
  56. package/dist/scoped-stack/family-policy.js.map +1 -1
  57. package/dist/scoped-stack/scoped-stack.d.ts +12 -5
  58. package/dist/scoped-stack/scoped-stack.d.ts.map +1 -1
  59. package/dist/scoped-stack/scoped-stack.js +52 -29
  60. package/dist/scoped-stack/scoped-stack.js.map +1 -1
  61. package/dist/stack/field-rules.d.ts +27 -0
  62. package/dist/stack/field-rules.d.ts.map +1 -0
  63. package/dist/stack/field-rules.js +50 -0
  64. package/dist/stack/field-rules.js.map +1 -0
  65. package/dist/stack/install-app.d.ts +2 -2
  66. package/dist/stack/install-app.d.ts.map +1 -1
  67. package/dist/stack/install-app.js +9 -9
  68. package/dist/stack/install-app.js.map +1 -1
  69. package/dist/stack/integrity.d.ts +9 -53
  70. package/dist/stack/integrity.d.ts.map +1 -1
  71. package/dist/stack/integrity.js +45 -105
  72. package/dist/stack/integrity.js.map +1 -1
  73. package/dist/stack/stack.d.ts +10 -11
  74. package/dist/stack/stack.d.ts.map +1 -1
  75. package/dist/stack/stack.js +35 -71
  76. package/dist/stack/stack.js.map +1 -1
  77. package/dist/stack/system-types.d.ts.map +1 -1
  78. package/dist/stack/system-types.js +1 -3
  79. package/dist/stack/system-types.js.map +1 -1
  80. package/dist/stack/type-grants.d.ts.map +1 -1
  81. package/dist/stack/type-grants.js +5 -2
  82. package/dist/stack/type-grants.js.map +1 -1
  83. package/dist/testing.d.ts +18 -17
  84. package/dist/testing.d.ts.map +1 -1
  85. package/dist/testing.js +43 -41
  86. package/dist/testing.js.map +1 -1
  87. package/dist/types/adapter.d.ts +71 -15
  88. package/dist/types/adapter.d.ts.map +1 -1
  89. package/dist/types/system.d.ts +1 -7
  90. package/dist/types/system.d.ts.map +1 -1
  91. package/dist/types/system.js.map +1 -1
  92. package/dist/validate.d.ts +2 -0
  93. package/dist/validate.d.ts.map +1 -1
  94. package/dist/validate.js +2 -2
  95. package/dist/validate.js.map +1 -1
  96. package/dist/wire/index.d.ts +1 -1
  97. package/dist/wire/index.d.ts.map +1 -1
  98. package/dist/wire/index.js +1 -1
  99. package/dist/wire/index.js.map +1 -1
  100. package/dist/wire/request.d.ts +8 -1
  101. package/dist/wire/request.d.ts.map +1 -1
  102. package/dist/wire/request.js +20 -0
  103. package/dist/wire/request.js.map +1 -1
  104. package/package.json +1 -1
  105. package/dist/stack/identity-bindings.d.ts +0 -13
  106. package/dist/stack/identity-bindings.d.ts.map +0 -1
  107. package/dist/stack/identity-bindings.js +0 -36
  108. package/dist/stack/identity-bindings.js.map +0 -1
package/README.md CHANGED
@@ -34,7 +34,6 @@ const keyPath = './my-stack.key.json'; // see "Key custody" under Identity for w
34
34
  const adapter = await LocalAdapter.open({
35
35
  path: dbPath,
36
36
  create: 'ifMissing',
37
- timezone: 'America/New_York',
38
37
  ownerEntityId: async () => {
39
38
  const { did, privateKey } = await generateDidKeypair();
40
39
  await writeFile(keyPath, JSON.stringify(await exportDidPrivateKeyJwk(privateKey)));
@@ -204,7 +203,7 @@ export const manifest: AppManifest = {
204
203
 
205
204
  **When the owner runs the app**, it opens with `Stack.open(adapter, { migrations })`, calls `install(stack)`, then `new Library(stack)`. A server hands each requester `new Library(stack.asActor(session))`.
206
205
 
207
- **When the app runs elsewhere** — holding its own key and reaching the stack through `APIAdapter` — it can't define types, so it asks: `adapter.requestInstall(manifest)` resolves to `pending` until the owner approves. The owner reviews `stack.planInstall(manifest, { did })` and applies it with `stack.installApp(plan)`, which defines the types, registers the app's key and grants it the requests. The app still opens with its `migrations`, then builds `new Library(stack)` over its own connection. See [App installs](https://github.com/haverstack/core/blob/main/docs/spec/apps.md).
206
+ **When the app runs elsewhere** — holding its own key and reaching the stack through `APIAdapter` — it can't define types, so it asks: `adapter.requestInstall(manifest)`, present when the server advertises install requests, resolves to `pending` until the owner approves. The owner reviews `stack.planInstall(manifest, { did })` and applies it with `stack.installApp(manifest, { did, fingerprint: plan.fingerprint })`, which defines the types, registers the app's key and grants it the requests. The app still opens with its `migrations`, then builds `new Library(stack)` over its own connection. See [App installs](https://github.com/haverstack/core/blob/main/docs/spec/apps.md).
208
207
 
209
208
  **Name content with an interface**, as above. `ContentOf` flattens its result, so a `type` alias shows the expanded object in editor hovers, while an interface keeps its name. typescript-eslint's recommended `no-empty-object-type` rule rejects an empty interface; its `allowInterfaces: 'with-single-extends'` option admits this one.
210
209
 
package/dist/access.d.ts CHANGED
@@ -12,7 +12,7 @@
12
12
  * it. Every tier is affirmative, so an element read past its own kind —
13
13
  * or carrying no kind at all — confers nothing.
14
14
  */
15
- import type { AuthorityAssociation, DataAssociation, EntityId, GroupRole, Grantee, RecordId, StackRecord } from './types/index.js';
15
+ import type { Actor, AuthorityAssociation, DataAssociation, EntityId, GroupRole, Grantee, RecordId, StackRecord, TypeId } from './types/index.js';
16
16
  import type { ValidationError } from './validate.js';
17
17
  /** Resolves a Record by ID, for walks that need no full adapter. */
18
18
  export type RecordResolver = (id: RecordId) => Promise<StackRecord | null>;
@@ -67,8 +67,12 @@ export declare function groupRoleFromAssociations(associations: DataAssociation[
67
67
  * the last. Reads associations alone, like groupRoleFromAssociations().
68
68
  */
69
69
  export declare function hasGroupAdmin(associations: DataAssociation[] | undefined): boolean;
70
- /** Bootstraps a `_group` record's first admin at create time. */
71
- export declare function stampGroupAdmin(associations: DataAssociation[] | undefined, creator: EntityId): DataAssociation[];
70
+ /**
71
+ * The associations a create stores: as given, plus a `_group`'s creator —
72
+ * the owner when none is named — stamped as its first admin.
73
+ * See docs/spec/identity.md § Group.
74
+ */
75
+ export declare function createAssociations(typeId: TypeId, associations: DataAssociation[] | undefined, createdBy: Actor | undefined, ownerEntityId: EntityId): DataAssociation[] | undefined;
72
76
  /**
73
77
  * Whether a request is the stack owner acting alone — the tier behind every
74
78
  * unconditional owner authority. Being the owner is never sufficient on its
@@ -1 +1 @@
1
- {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EAEV,oBAAoB,EACpB,eAAe,EACf,QAAQ,EAER,SAAS,EACT,OAAO,EACP,QAAQ,EAER,WAAW,EACZ,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,oEAAoE;AACpE,MAAM,MAAM,cAAc,GAAG,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAE1E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,EAAE,CAKvE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjD,OAAO,CAAC,OAAO,CAAC,CAelB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,oBAAoB,EAAE,GAAG,SAAS,EAC/C,IAAI,SAAgB,GACnB,eAAe,EAAE,CAcnB;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,CAElF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,eAAe,EAAE,GAAG,SAAS,EAC3C,QAAQ,EAAE,QAAQ,GACjB,SAAS,GAAG,IAAI,CASlB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,eAAe,EAAE,GAAG,SAAS,GAAG,OAAO,CAElF;AAkBD,iEAAiE;AACjE,wBAAgB,eAAe,CAC7B,YAAY,EAAE,eAAe,EAAE,GAAG,SAAS,EAC3C,OAAO,EAAE,QAAQ,GAChB,eAAe,EAAE,CAUnB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE;IAAE,SAAS,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,EACpE,aAAa,EAAE,QAAQ,GACtB,OAAO,CAGT"}
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,KAAK,EACV,KAAK,EAEL,oBAAoB,EACpB,eAAe,EACf,QAAQ,EAER,SAAS,EACT,OAAO,EACP,QAAQ,EAER,WAAW,EACX,MAAM,EACP,MAAM,kBAAkB,CAAC;AAG1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAErD,oEAAoE;AACpE,MAAM,MAAM,cAAc,GAAG,CAAC,EAAE,EAAE,QAAQ,KAAK,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;AAE3E;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,WAAW,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAE1E;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,oBAAoB,EAAE,CAKvE;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjD,OAAO,CAAC,OAAO,CAAC,CAelB;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,oBAAoB,EAAE,GAAG,SAAS,EAC/C,IAAI,SAAgB,GACnB,eAAe,EAAE,CAcnB;AAED,wEAAwE;AACxE,wBAAgB,aAAa,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,EAAE,QAAQ,EAAE,SAAS,GAAG,OAAO,CAElF;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAE1D;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,eAAe,EAAE,GAAG,SAAS,EAC3C,QAAQ,EAAE,QAAQ,GACjB,SAAS,GAAG,IAAI,CASlB;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,eAAe,EAAE,GAAG,SAAS,GAAG,OAAO,CAElF;AAkBD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,eAAe,EAAE,GAAG,SAAS,EAC3C,SAAS,EAAE,KAAK,GAAG,SAAS,EAC5B,aAAa,EAAE,QAAQ,GACtB,eAAe,EAAE,GAAG,SAAS,CAG/B;AAiBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE;IAAE,SAAS,EAAE,QAAQ,GAAG,IAAI,CAAC;IAAC,WAAW,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;CAAE,EACpE,aAAa,EAAE,QAAQ,GACtB,OAAO,CAGT"}
package/dist/access.js CHANGED
@@ -122,8 +122,17 @@ function isGroupAdminAssociation(association) {
122
122
  association.label === 'admin' &&
123
123
  association.target.kind === 'entity');
124
124
  }
125
- /** Bootstraps a `_group` record's first admin at create time. */
126
- export function stampGroupAdmin(associations, creator) {
125
+ /**
126
+ * The associations a create stores: as given, plus a `_group`'s creator —
127
+ * the owner when none is named — stamped as its first admin.
128
+ * See docs/spec/identity.md § Group.
129
+ */
130
+ export function createAssociations(typeId, associations, createdBy, ownerEntityId) {
131
+ if (baseIdOf(typeId) !== SYSTEM_TYPES.GROUP)
132
+ return associations;
133
+ return stampGroupAdmin(associations, createdBy?.subjectId ?? ownerEntityId);
134
+ }
135
+ function stampGroupAdmin(associations, creator) {
127
136
  const list = associations ?? [];
128
137
  const alreadyAdmin = list.some((a) => isGroupAdminAssociation(a) && a.target.entityId === creator);
129
138
  if (alreadyAdmin)
@@ -1 +1 @@
1
- {"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Blob listing windows and file ids
3
+ * -------------------------------------------------------
4
+ * `listBlobs()` reads in `fileId` order and pages forward from
5
+ * `afterFileId`, on every adapter. An adapter whose storage hands back an
6
+ * unordered set of names windows it here, so the order and the cursor mean
7
+ * the same thing whatever stores the bytes. See docs/spec/data-model.md
8
+ * § List order.
9
+ */
10
+ import type { BlobsQuery, FileId } from '../types/index.js';
11
+ /** The `fileId`s a `listBlobs(query)` answers with, out of every one stored. */
12
+ export declare function blobWindow(fileIds: Iterable<FileId>, query?: BlobsQuery): FileId[];
13
+ /**
14
+ * Refuses a name no blob could have, before a store or a page is asked for
15
+ * it. `label` names where it arrived, such as a request's `afterFileId`.
16
+ */
17
+ export declare function assertFileId(fileId: string, label?: string): void;
18
+ //# sourceMappingURL=blobs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blobs.d.ts","sourceRoot":"","sources":["../../src/adapter/blobs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG5D,gFAAgF;AAChF,wBAAgB,UAAU,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,GAAE,UAAe,GAAG,MAAM,EAAE,CAItF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAW,GAAG,IAAI,CAInE"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Blob listing windows and file ids
3
+ * -------------------------------------------------------
4
+ * `listBlobs()` reads in `fileId` order and pages forward from
5
+ * `afterFileId`, on every adapter. An adapter whose storage hands back an
6
+ * unordered set of names windows it here, so the order and the cursor mean
7
+ * the same thing whatever stores the bytes. See docs/spec/data-model.md
8
+ * § List order.
9
+ */
10
+ import { StackBadRequestError } from '../errors.js';
11
+ import { FILE_ID_RE } from '../validate.js';
12
+ /** The `fileId`s a `listBlobs(query)` answers with, out of every one stored. */
13
+ export function blobWindow(fileIds, query = {}) {
14
+ const { afterFileId, limit } = query;
15
+ const after = [...fileIds].filter((id) => afterFileId === undefined || id > afterFileId).sort();
16
+ return limit === undefined ? after : after.slice(0, limit);
17
+ }
18
+ /**
19
+ * Refuses a name no blob could have, before a store or a page is asked for
20
+ * it. `label` names where it arrived, such as a request's `afterFileId`.
21
+ */
22
+ export function assertFileId(fileId, label = 'fileId') {
23
+ if (!FILE_ID_RE.test(fileId)) {
24
+ throw new StackBadRequestError(`Invalid ${label}: expected 64-character lowercase hex string`);
25
+ }
26
+ }
27
+ //# sourceMappingURL=blobs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blobs.js","sourceRoot":"","sources":["../../src/adapter/blobs.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,gFAAgF;AAChF,MAAM,UAAU,UAAU,CAAC,OAAyB,EAAE,QAAoB,EAAE;IAC1E,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IACrC,MAAM,KAAK,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,WAAW,KAAK,SAAS,IAAI,EAAE,GAAG,WAAW,CAAC,CAAC,IAAI,EAAE,CAAC;IAChG,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,KAAK,GAAG,QAAQ;IAC3D,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,oBAAoB,CAAC,WAAW,KAAK,8CAA8C,CAAC,CAAC;IACjG,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"combine.d.ts","sourceRoot":"","sources":["../../src/adapter/combine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAGV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAGjB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,gBAAgB,CAAC;CACxB,GAAG,YAAY,CA8Ef"}
1
+ {"version":3,"file":"combine.d.ts","sourceRoot":"","sources":["../../src/adapter/combine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAKV,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAGjB,MAAM,mBAAmB,CAAC;AAG3B;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,IAAI,EAAE,gBAAgB,CAAC;CACxB,GAAG,YAAY,CAqFf"}
@@ -5,6 +5,7 @@
5
5
  * deployment can keep records and bytes in different backends without
6
6
  * either adapter knowing about the other.
7
7
  */
8
+ import { combinedHead } from './head.js';
8
9
  /**
9
10
  * Compose a StackRecordAdapter and a StackBlobAdapter into a single StackAdapter.
10
11
  * Use this when you want different backends for records and blobs, e.g.:
@@ -20,8 +21,9 @@ export function combineAdapters(parts) {
20
21
  get ownerEntityId() {
21
22
  return parts.record.ownerEntityId;
22
23
  },
23
- get timezone() {
24
- return parts.record.timezone;
24
+ // The record half's, since writers names who writes the Records.
25
+ get writers() {
26
+ return parts.record.writers;
25
27
  },
26
28
  createRecord: (r, opts) => parts.record.createRecord(r, opts),
27
29
  getRecord: (id) => parts.record.getRecord(id),
@@ -37,7 +39,6 @@ export function combineAdapters(parts) {
37
39
  setAccess: (id, list, opts) => parts.record.setAccess(id, list, opts),
38
40
  getVersions: (id, query) => parts.record.getVersions(id, query),
39
41
  getVersion: (id, v) => parts.record.getVersion(id, v),
40
- saveVersion: (id, v) => parts.record.saveVersion(id, v),
41
42
  getJournal: (id, query) => parts.record.getJournal(id, query),
42
43
  restoreVersion: (id, v, opts) => parts.record.restoreVersion(id, v, opts),
43
44
  commitMigration: (id, toTypeId, content, opts) => parts.record.commitMigration(id, toTypeId, content, opts),
@@ -50,13 +51,14 @@ export function combineAdapters(parts) {
50
51
  ...(parts.record.deleteUnreferencedAttachmentRecords && {
51
52
  deleteUnreferencedAttachmentRecords: (fileId, metadataBaseId) => parts.record.deleteUnreferencedAttachmentRecords(fileId, metadataBaseId),
52
53
  }),
54
+ ...(parts.record.importRecord && {
55
+ importRecord: (r, history) => parts.record.importRecord(r, history),
56
+ }),
53
57
  ...(parts.record.queryReadable && {
54
58
  queryReadable: (q, reach) => parts.record.queryReadable(q, reach),
55
59
  }),
56
- // Forwarded on the same terms, and it decides more than it looks:
57
- // Stack.relaysChanges reads its presence, so dropping it here would
58
- // leave a combined stack quietly emitting only its own writes while a
59
- // remote record backend's feed went unread.
60
+ // Forwarded on the same terms: dropping it would leave a shared record
61
+ // backend's feed unread, and Stack would refuse to subscribe at all.
60
62
  ...(parts.record.subscribeChanges && {
61
63
  subscribeChanges: (opts, handler) => parts.record.subscribeChanges(opts, handler),
62
64
  }),
@@ -68,7 +70,12 @@ export function combineAdapters(parts) {
68
70
  getBlob: (id) => parts.blob.getBlob(id),
69
71
  deleteBlob: (id) => parts.blob.deleteBlob(id),
70
72
  ...(parts.blob.listBlobs && {
71
- listBlobs: () => parts.blob.listBlobs(),
73
+ listBlobs: (query) => parts.blob.listBlobs(query),
74
+ }),
75
+ // One head for the whole store, so a write to either half moves it.
76
+ ...(parts.record.head &&
77
+ parts.blob.head && {
78
+ head: async () => combinedHead(await parts.record.head(), await parts.blob.head()),
72
79
  }),
73
80
  async flush() {
74
81
  await parts.record.flush?.();
@@ -1 +1 @@
1
- {"version":3,"file":"combine.js","sourceRoot":"","sources":["../../src/adapter/combine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"combine.js","sourceRoot":"","sources":["../../src/adapter/combine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Copying a stack
3
+ * -------------------------------------------------------
4
+ * One stack, read in full from one adapter and written in full to a new
5
+ * store: every Record (soft-deleted and unlisted included) with its version
6
+ * snapshots and journal, `_config` among them as the seed the store is
7
+ * created from, every Type, and every blob. Each is read as the store
8
+ * enumerates it, never by what a Record says, so nothing is filtered on the
9
+ * way. Export, import and moving
10
+ * between storage engines are all this one call, with a different source
11
+ * and a different kind of store to create. Full trust, like any direct
12
+ * adapter access: authorship and history land as recorded, which no write
13
+ * through Stack may do.
14
+ *
15
+ * A copy reads one moment of its source: it reads the source's head before
16
+ * and after, and refuses the copy if the two differ. One rule for every
17
+ * source, whoever else writes to it. See docs/spec/portability.md.
18
+ */
19
+ import type { StackAdapter, StoreSeed } from '../types/index.js';
20
+ /** Creates a new store from `seed`: `LocalAdapter.open({ path, seed })`, say. */
21
+ export type CreateStore = (seed: StoreSeed) => Promise<StackAdapter> | StackAdapter;
22
+ /**
23
+ * Copy everything `from` holds into the store `create` makes from its
24
+ * `_config` record and that record's history, and return that store, open.
25
+ * Not atomic: a failure closes the store part-written, and the caller, whose
26
+ * store it is, removes it. A source written meanwhile is refused with
27
+ * StackConflictError, and the copy is run again into a new store.
28
+ * See docs/spec/portability.md § Copying a stack.
29
+ */
30
+ export declare function copyStack(from: StackAdapter, create: CreateStore): Promise<StackAdapter>;
31
+ //# sourceMappingURL=copy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.d.ts","sourceRoot":"","sources":["../../src/adapter/copy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAIV,YAAY,EAEZ,SAAS,EACV,MAAM,mBAAmB,CAAC;AAG3B,iFAAiF;AACjF,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,SAAS,KAAK,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;AAYpF;;;;;;;GAOG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAoC9F"}
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Copying a stack
3
+ * -------------------------------------------------------
4
+ * One stack, read in full from one adapter and written in full to a new
5
+ * store: every Record (soft-deleted and unlisted included) with its version
6
+ * snapshots and journal, `_config` among them as the seed the store is
7
+ * created from, every Type, and every blob. Each is read as the store
8
+ * enumerates it, never by what a Record says, so nothing is filtered on the
9
+ * way. Export, import and moving
10
+ * between storage engines are all this one call, with a different source
11
+ * and a different kind of store to create. Full trust, like any direct
12
+ * adapter access: authorship and history land as recorded, which no write
13
+ * through Stack may do.
14
+ *
15
+ * A copy reads one moment of its source: it reads the source's head before
16
+ * and after, and refuses the copy if the two differ. One rule for every
17
+ * source, whoever else writes to it. See docs/spec/portability.md.
18
+ */
19
+ import { InvalidAdapterError, OwnerMismatchError, StackConflictError } from '../errors.js';
20
+ import { resolveQuery } from '../query-validation.js';
21
+ import { SYSTEM_TYPES } from '../types/index.js';
22
+ /** Records read per page; any size works, as each page is written before the next is read. */
23
+ const PAGE_SIZE = 100;
24
+ /** Every Record a store holds but `_config`, which no query reaches: a store is created from it. */
25
+ const EVERYTHING = {
26
+ filter: { includeDeleted: true, includeUnlisted: true },
27
+ sort: { field: 'createdAt', direction: 'asc' },
28
+ limit: PAGE_SIZE,
29
+ };
30
+ /**
31
+ * Copy everything `from` holds into the store `create` makes from its
32
+ * `_config` record and that record's history, and return that store, open.
33
+ * Not atomic: a failure closes the store part-written, and the caller, whose
34
+ * store it is, removes it. A source written meanwhile is refused with
35
+ * StackConflictError, and the copy is run again into a new store.
36
+ * See docs/spec/portability.md § Copying a stack.
37
+ */
38
+ export async function copyStack(from, create) {
39
+ const listBlobs = from.listBlobs?.bind(from);
40
+ if (!listBlobs)
41
+ refuseSource('it has no listBlobs(), so its blobs cannot be enumerated');
42
+ const head = from.head?.bind(from);
43
+ if (!head)
44
+ refuseSource('it has no head(), so a write during the copy could not be detected');
45
+ // Before the first read, so every write that could land during one moves it.
46
+ const started = await head();
47
+ const config = await from.getRecord(SYSTEM_TYPES.CONFIG);
48
+ if (!config)
49
+ refuseSource('it holds no _config record');
50
+ const [versions, journal] = await Promise.all([
51
+ from.getVersions(config.id),
52
+ from.getJournal(config.id),
53
+ ]);
54
+ const to = await create({ config, history: { versions, journal } });
55
+ try {
56
+ const importRecord = to.importRecord?.bind(to);
57
+ if (!importRecord)
58
+ refuseTarget('it has no importRecord(), so it cannot write history');
59
+ const listHeld = to.listBlobs?.bind(to);
60
+ if (!listHeld)
61
+ refuseTarget('it has no listBlobs(), so it could not be copied from in turn');
62
+ if (!to.head)
63
+ refuseTarget('it has no head(), so it could not be copied from in turn');
64
+ await assertNewStore(to, config.content.ownerEntityId, listHeld);
65
+ for (const type of await from.listTypes())
66
+ await to.saveType(type);
67
+ // Bytes before the Records that name them, as every upload writes them.
68
+ await copyBlobs(from, to, listBlobs);
69
+ await copyRecords(from, importRecord);
70
+ if ((await head()) !== started) {
71
+ throw new StackConflictError('The source was written while it was copied. Copy it again into a new store.');
72
+ }
73
+ return to;
74
+ }
75
+ catch (err) {
76
+ // The failure that stopped the copy is the one to report.
77
+ await to.close?.().catch(() => { });
78
+ throw err;
79
+ }
80
+ }
81
+ function refuseSource(why) {
82
+ throw new InvalidAdapterError(`Cannot copy from this adapter: ${why}.`);
83
+ }
84
+ function refuseTarget(why) {
85
+ throw new InvalidAdapterError(`Cannot copy into the store create() returned: ${why}.`);
86
+ }
87
+ /**
88
+ * A target is a store as its adapter creates one: the source's owner,
89
+ * checked as open() checks it, and nothing held yet — no Record, no Type, no
90
+ * blob. Every end of a copy lists all it holds and has a head, so a target
91
+ * is itself a store a later copy can read.
92
+ */
93
+ async function assertNewStore(to, ownerEntityId, listHeld) {
94
+ if (to.ownerEntityId !== ownerEntityId) {
95
+ throw new OwnerMismatchError(ownerEntityId, to.ownerEntityId, 'the store create() returned');
96
+ }
97
+ if ((await to.queryRecords(resolveQuery({ ...EVERYTHING, limit: 1 }))).records.length) {
98
+ refuseTarget('it already holds Records');
99
+ }
100
+ if ((await to.listTypes()).length)
101
+ refuseTarget('it already holds Types');
102
+ if ((await listHeld({ limit: 1 })).length)
103
+ refuseTarget('it already holds blobs');
104
+ }
105
+ async function copyBlobs(from, to, listBlobs) {
106
+ let afterFileId;
107
+ for (;;) {
108
+ const page = await listBlobs({ afterFileId, limit: PAGE_SIZE });
109
+ for (const { fileId } of page)
110
+ await to.putBlob(await from.getBlob(fileId));
111
+ if (page.length < PAGE_SIZE)
112
+ return;
113
+ afterFileId = page[page.length - 1].fileId;
114
+ }
115
+ }
116
+ async function copyRecords(from, importRecord) {
117
+ let cursor;
118
+ do {
119
+ const page = await from.queryRecords(resolveQuery({ ...EVERYTHING, cursor }));
120
+ for (const record of page.records) {
121
+ // One Record's history is read whole, as importRecord() takes it.
122
+ const [versions, journal] = await Promise.all([
123
+ from.getVersions(record.id),
124
+ from.getJournal(record.id),
125
+ ]);
126
+ await importRecord(record, { versions, journal });
127
+ }
128
+ cursor = page.cursor ?? undefined;
129
+ } while (cursor);
130
+ }
131
+ //# sourceMappingURL=copy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"copy.js","sourceRoot":"","sources":["../../src/adapter/copy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Write heads
3
+ * -------------------------------------------------------
4
+ * A head says where a store's writes stand, so a reader that takes one
5
+ * before and one after learns whether anything was written between. A
6
+ * local store's writer is the process that owns it, so that process can
7
+ * count its own writes: trackWrites() wraps every write method an adapter
8
+ * has, so no method has to remember to. The count starts in a random
9
+ * epoch, so a store reopened (or a server restarted) never returns to a
10
+ * head it reported before. See docs/spec/portability.md § Copying a stack.
11
+ */
12
+ /** One store's writes, counted for its `head()`. */
13
+ declare class WriteHead {
14
+ private readonly epoch;
15
+ private settled;
16
+ private inFlight;
17
+ private busyReads;
18
+ /**
19
+ * A write in flight may land on either side of a read, so a head read
20
+ * meanwhile matches no other head; one read after it settles differs from
21
+ * every head read before.
22
+ */
23
+ read(): string;
24
+ track<T>(write: () => Promise<T>): Promise<T>;
25
+ }
26
+ /** The head a `head()` reports. */
27
+ export type { WriteHead };
28
+ /**
29
+ * Wrap every write method `adapter` has so it moves the returned head, and
30
+ * return that head for the adapter's `head()` to read. Call once, from the
31
+ * adapter's own constructor: it wraps the methods present then, so a write
32
+ * method assigned as a field after that call goes uncounted (the
33
+ * conformance suite's head tests catch one).
34
+ */
35
+ export declare function trackWrites(adapter: object): WriteHead;
36
+ /** The head of a store made of two halves: it moves when either does. */
37
+ export declare function combinedHead(record: string, blob: string): string;
38
+ //# sourceMappingURL=head.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../src/adapter/head.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AA6BH,oDAAoD;AACpD,cAAM,SAAS;IACb,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuB;IAC7C,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,SAAS,CAAK;IAEtB;;;;OAIG;IACH,IAAI,IAAI,MAAM;IAKR,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CASpD;AAED,mCAAmC;AACnC,YAAY,EAAE,SAAS,EAAE,CAAC;AAE1B;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAUtD;AAED,yEAAyE;AACzE,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjE"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Write heads
3
+ * -------------------------------------------------------
4
+ * A head says where a store's writes stand, so a reader that takes one
5
+ * before and one after learns whether anything was written between. A
6
+ * local store's writer is the process that owns it, so that process can
7
+ * count its own writes: trackWrites() wraps every write method an adapter
8
+ * has, so no method has to remember to. The count starts in a random
9
+ * epoch, so a store reopened (or a server restarted) never returns to a
10
+ * head it reported before. See docs/spec/portability.md § Copying a stack.
11
+ */
12
+ /**
13
+ * Every write method, keyed so a method added to StackAdapter fails
14
+ * typecheck here until it is listed or named a read.
15
+ */
16
+ const WRITE_METHODS = {
17
+ createRecord: true,
18
+ importRecord: true,
19
+ patchContent: true,
20
+ deleteRecord: true,
21
+ undeleteRecord: true,
22
+ setParent: true,
23
+ setUnlisted: true,
24
+ editAssociations: true,
25
+ setAssociations: true,
26
+ editAccess: true,
27
+ setAccess: true,
28
+ restoreVersion: true,
29
+ commitMigration: true,
30
+ saveType: true,
31
+ deleteUnreferencedAttachmentRecords: true,
32
+ putBlob: true,
33
+ deleteBlob: true,
34
+ putAttachmentWithMetadata: true,
35
+ };
36
+ /** One store's writes, counted for its `head()`. */
37
+ class WriteHead {
38
+ epoch = crypto.randomUUID();
39
+ settled = 0;
40
+ inFlight = 0;
41
+ busyReads = 0;
42
+ /**
43
+ * A write in flight may land on either side of a read, so a head read
44
+ * meanwhile matches no other head; one read after it settles differs from
45
+ * every head read before.
46
+ */
47
+ read() {
48
+ if (this.inFlight)
49
+ return `${this.epoch}.${this.settled}.${++this.busyReads}`;
50
+ return `${this.epoch}.${this.settled}`;
51
+ }
52
+ async track(write) {
53
+ this.inFlight++;
54
+ try {
55
+ return await write();
56
+ }
57
+ finally {
58
+ this.inFlight--;
59
+ this.settled++;
60
+ }
61
+ }
62
+ }
63
+ /**
64
+ * Wrap every write method `adapter` has so it moves the returned head, and
65
+ * return that head for the adapter's `head()` to read. Call once, from the
66
+ * adapter's own constructor: it wraps the methods present then, so a write
67
+ * method assigned as a field after that call goes uncounted (the
68
+ * conformance suite's head tests catch one).
69
+ */
70
+ export function trackWrites(adapter) {
71
+ const head = new WriteHead();
72
+ const members = adapter;
73
+ for (const name of Object.keys(WRITE_METHODS)) {
74
+ const write = members[name];
75
+ if (typeof write !== 'function')
76
+ continue;
77
+ members[name] = (...args) => head.track(() => write.apply(adapter, args));
78
+ }
79
+ return head;
80
+ }
81
+ /** The head of a store made of two halves: it moves when either does. */
82
+ export function combinedHead(record, blob) {
83
+ return `${record}/${blob}`;
84
+ }
85
+ //# sourceMappingURL=head.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head.js","sourceRoot":"","sources":["../../src/adapter/head.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH;;;GAGG;AACH,MAAM,aAAa,GAAmC;IACpD,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,IAAI;IAClB,YAAY,EAAE,IAAI;IAClB,cAAc,EAAE,IAAI;IACpB,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,IAAI;IACjB,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI;IACrB,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,IAAI;IACpB,eAAe,EAAE,IAAI;IACrB,QAAQ,EAAE,IAAI;IACd,mCAAmC,EAAE,IAAI;IACzC,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,yBAAyB,EAAE,IAAI;CAChC,CAAC;AAEF,oDAAoD;AACpD,MAAM,SAAS;IACI,KAAK,GAAG,MAAM,CAAC,UAAU,EAAE,CAAC;IACrC,OAAO,GAAG,CAAC,CAAC;IACZ,QAAQ,GAAG,CAAC,CAAC;IACb,SAAS,GAAG,CAAC,CAAC;IAEtB;;;;OAIG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,QAAQ;YAAE,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC;QAC9E,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,KAAK,CAAI,KAAuB;QACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,EAAE,CAAC;QACvB,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC;IACH,CAAC;CACF;AAKD;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,IAAI,GAAG,IAAI,SAAS,EAAE,CAAC;IAC7B,MAAM,OAAO,GAAG,OAAkC,CAAC;IACnD,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5B,IAAI,OAAO,KAAK,KAAK,UAAU;YAAE,SAAS;QAC1C,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE,CACrC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAE,KAA+C,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;IAC5F,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,IAAY;IACvD,OAAO,GAAG,MAAM,IAAI,IAAI,EAAE,CAAC;AAC7B,CAAC"}
@@ -7,10 +7,17 @@
7
7
  * adapters). Types an app reads too, such as StackCapabilities, live in
8
8
  * the root entry point instead: every export has exactly one home.
9
9
  */
10
- export type { AdapterQuery, PlainQuery, AdapterSort, StackAdapter, StackRecordAdapter, StackBlobAdapter, BlobInfo, SnapshotOptions, JournalEntryInput, JournalOptions, MutateOptions, AspectWriteOptions, ElementWriteOptions, Reach, } from '../types/index.js';
10
+ export type { AdapterQuery, PlainQuery, AdapterSort, StackAdapter, StackRecordAdapter, StackBlobAdapter, BlobInfo, BlobsQuery, StoreWriters, StoreReadMember, StoreWriteMethod, RecordWriteMethod, BlobWriteMethod, SnapshotOptions, JournalEntryInput, JournalOptions, MutateOptions, AspectWriteOptions, ElementWriteOptions, Reach, RecordHistory, StoreSeed, } from '../types/index.js';
11
11
  export { sameAssociationSet } from '../associations/identity.js';
12
- export { ElementSetMovedError, OwnerMismatchError, softDeletedRefusal } from '../errors.js';
12
+ export { ElementSetMovedError, FormatMismatchError, OwnerMismatchError, softDeletedRefusal, } from '../errors.js';
13
+ export { assertFileId, blobWindow } from './blobs.js';
14
+ export { trackWrites, combinedHead } from './head.js';
15
+ export type { WriteHead } from './head.js';
16
+ export { FILE_ID_RE } from '../validate.js';
13
17
  export { combineAdapters } from './combine.js';
18
+ export { copyStack } from './copy.js';
19
+ export type { CreateStore } from './copy.js';
20
+ export { newStoreSeed } from './seed.js';
14
21
  export { inReach } from './reach.js';
15
22
  export type { ReachedRecord } from './reach.js';
16
23
  export { assertQueryCapabilities, assertValidSort, resolveQuery, assertValidAssociationFilters, assertValidJournalQuery, assertValidVersionsQuery, filtersContent, parseContentFilterKey, } from '../query-validation.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACR,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,GACN,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,YAAY,EACZ,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,YAAY,EACV,YAAY,EACZ,UAAU,EACV,WAAW,EACX,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,iBAAiB,EACjB,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,mBAAmB,EACnB,KAAK,EACL,aAAa,EACb,SAAS,GACV,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACtD,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,YAAY,EACZ,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,GACb,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC"}
@@ -8,8 +8,13 @@
8
8
  * the root entry point instead: every export has exactly one home.
9
9
  */
10
10
  export { sameAssociationSet } from '../associations/identity.js';
11
- export { ElementSetMovedError, OwnerMismatchError, softDeletedRefusal } from '../errors.js';
11
+ export { ElementSetMovedError, FormatMismatchError, OwnerMismatchError, softDeletedRefusal, } from '../errors.js';
12
+ export { assertFileId, blobWindow } from './blobs.js';
13
+ export { trackWrites, combinedHead } from './head.js';
14
+ export { FILE_ID_RE } from '../validate.js';
12
15
  export { combineAdapters } from './combine.js';
16
+ export { copyStack } from './copy.js';
17
+ export { newStoreSeed } from './seed.js';
13
18
  export { inReach } from './reach.js';
14
19
  export { assertQueryCapabilities, assertValidSort, resolveQuery, assertValidAssociationFilters, assertValidJournalQuery, assertValidVersionsQuery, filtersContent, parseContentFilterKey, } from '../query-validation.js';
15
20
  export { contentSortEntry, contentSortKey, compareSortEntries, constantSortEntry, sortConstant, } from './sort.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAkBH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,YAAY,EACZ,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,GACb,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapter/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0BH,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEtD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,YAAY,EACZ,6BAA6B,EAC7B,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EACd,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,GACb,MAAM,WAAW,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Store seeds
3
+ * -------------------------------------------------------
4
+ * A store is created holding one Record, `_config`, which says whose stack
5
+ * it is. A seed is that Record with its history: fresh for a new stack, the
6
+ * source's own for a copy, so the one Record every store starts with is
7
+ * written the way every other Record is. See docs/spec/adapters.md
8
+ * § Construction.
9
+ */
10
+ import type { ConfigContent, StoreSeed } from '../types/index.js';
11
+ /** The seed of a stack that has no past: `_config` at version 1, holding `config`. */
12
+ export declare function newStoreSeed(config: ConfigContent): StoreSeed;
13
+ //# sourceMappingURL=seed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../src/adapter/seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAGlE,sFAAsF;AACtF,wBAAgB,YAAY,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,CAa7D"}