@superbee/core 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 (145) hide show
  1. package/dist/backend.d.ts +77 -0
  2. package/dist/backend.d.ts.map +1 -0
  3. package/dist/backend.js +380 -0
  4. package/dist/backend.js.map +1 -0
  5. package/dist/bundle.d.ts +38 -0
  6. package/dist/bundle.d.ts.map +1 -0
  7. package/dist/bundle.js +107 -0
  8. package/dist/bundle.js.map +1 -0
  9. package/dist/content-type.d.ts +72 -0
  10. package/dist/content-type.d.ts.map +1 -0
  11. package/dist/content-type.js +149 -0
  12. package/dist/content-type.js.map +1 -0
  13. package/dist/document-mutation.d.ts +83 -0
  14. package/dist/document-mutation.d.ts.map +1 -0
  15. package/dist/document-mutation.js +319 -0
  16. package/dist/document-mutation.js.map +1 -0
  17. package/dist/document-precondition.d.ts +62 -0
  18. package/dist/document-precondition.d.ts.map +1 -0
  19. package/dist/document-precondition.js +134 -0
  20. package/dist/document-precondition.js.map +1 -0
  21. package/dist/document-write-policy.d.ts +42 -0
  22. package/dist/document-write-policy.d.ts.map +1 -0
  23. package/dist/document-write-policy.js +134 -0
  24. package/dist/document-write-policy.js.map +1 -0
  25. package/dist/engine.d.ts +48 -0
  26. package/dist/engine.d.ts.map +1 -0
  27. package/dist/engine.js +209 -0
  28. package/dist/engine.js.map +1 -0
  29. package/dist/errors.d.ts +36 -0
  30. package/dist/errors.d.ts.map +1 -0
  31. package/dist/errors.js +50 -0
  32. package/dist/errors.js.map +1 -0
  33. package/dist/filesystem-identity.d.ts +208 -0
  34. package/dist/filesystem-identity.d.ts.map +1 -0
  35. package/dist/filesystem-identity.js +675 -0
  36. package/dist/filesystem-identity.js.map +1 -0
  37. package/dist/filesystem-lock.d.ts +65 -0
  38. package/dist/filesystem-lock.d.ts.map +1 -0
  39. package/dist/filesystem-lock.js +460 -0
  40. package/dist/filesystem-lock.js.map +1 -0
  41. package/dist/freshness.d.ts +31 -0
  42. package/dist/freshness.d.ts.map +1 -0
  43. package/dist/freshness.js +98 -0
  44. package/dist/freshness.js.map +1 -0
  45. package/dist/frontmatter-contract.d.ts +17 -0
  46. package/dist/frontmatter-contract.d.ts.map +1 -0
  47. package/dist/frontmatter-contract.js +29 -0
  48. package/dist/frontmatter-contract.js.map +1 -0
  49. package/dist/frontmatter.d.ts +30 -0
  50. package/dist/frontmatter.d.ts.map +1 -0
  51. package/dist/frontmatter.js +115 -0
  52. package/dist/frontmatter.js.map +1 -0
  53. package/dist/index-marker.d.ts +3 -0
  54. package/dist/index-marker.d.ts.map +1 -0
  55. package/dist/index-marker.js +3 -0
  56. package/dist/index-marker.js.map +1 -0
  57. package/dist/index-projection.d.ts +79 -0
  58. package/dist/index-projection.d.ts.map +1 -0
  59. package/dist/index-projection.js +245 -0
  60. package/dist/index-projection.js.map +1 -0
  61. package/dist/index.d.ts +68 -0
  62. package/dist/index.d.ts.map +1 -0
  63. package/dist/index.js +110 -0
  64. package/dist/index.js.map +1 -0
  65. package/dist/kinds-load.d.ts +13 -0
  66. package/dist/kinds-load.d.ts.map +1 -0
  67. package/dist/kinds-load.js +34 -0
  68. package/dist/kinds-load.js.map +1 -0
  69. package/dist/kinds.d.ts +241 -0
  70. package/dist/kinds.d.ts.map +1 -0
  71. package/dist/kinds.js +1001 -0
  72. package/dist/kinds.js.map +1 -0
  73. package/dist/links.d.ts +62 -0
  74. package/dist/links.d.ts.map +1 -0
  75. package/dist/links.js +203 -0
  76. package/dist/links.js.map +1 -0
  77. package/dist/meaningful-change-time.d.ts +11 -0
  78. package/dist/meaningful-change-time.d.ts.map +1 -0
  79. package/dist/meaningful-change-time.js +16 -0
  80. package/dist/meaningful-change-time.js.map +1 -0
  81. package/dist/memory-backend.d.ts +55 -0
  82. package/dist/memory-backend.d.ts.map +1 -0
  83. package/dist/memory-backend.js +214 -0
  84. package/dist/memory-backend.js.map +1 -0
  85. package/dist/mutation-attribution.d.ts +19 -0
  86. package/dist/mutation-attribution.d.ts.map +1 -0
  87. package/dist/mutation-attribution.js +34 -0
  88. package/dist/mutation-attribution.js.map +1 -0
  89. package/dist/mutation.d.ts +89 -0
  90. package/dist/mutation.d.ts.map +1 -0
  91. package/dist/mutation.js +94 -0
  92. package/dist/mutation.js.map +1 -0
  93. package/dist/page.d.ts +87 -0
  94. package/dist/page.d.ts.map +1 -0
  95. package/dist/page.js +151 -0
  96. package/dist/page.js.map +1 -0
  97. package/dist/paths.d.ts +78 -0
  98. package/dist/paths.d.ts.map +1 -0
  99. package/dist/paths.js +148 -0
  100. package/dist/paths.js.map +1 -0
  101. package/dist/portable-frontmatter.d.ts +8 -0
  102. package/dist/portable-frontmatter.d.ts.map +1 -0
  103. package/dist/portable-frontmatter.js +35 -0
  104. package/dist/portable-frontmatter.js.map +1 -0
  105. package/dist/publication-filesystem.d.ts +6 -0
  106. package/dist/publication-filesystem.d.ts.map +1 -0
  107. package/dist/publication-filesystem.js +6 -0
  108. package/dist/publication-filesystem.js.map +1 -0
  109. package/dist/query-filter.d.ts +12 -0
  110. package/dist/query-filter.d.ts.map +1 -0
  111. package/dist/query-filter.js +29 -0
  112. package/dist/query-filter.js.map +1 -0
  113. package/dist/query-selection.d.ts +25 -0
  114. package/dist/query-selection.d.ts.map +1 -0
  115. package/dist/query-selection.js +48 -0
  116. package/dist/query-selection.js.map +1 -0
  117. package/dist/remote-backend.d.ts +152 -0
  118. package/dist/remote-backend.d.ts.map +1 -0
  119. package/dist/remote-backend.js +505 -0
  120. package/dist/remote-backend.js.map +1 -0
  121. package/dist/remote.d.ts +4 -0
  122. package/dist/remote.d.ts.map +1 -0
  123. package/dist/remote.js +3 -0
  124. package/dist/remote.js.map +1 -0
  125. package/dist/storage.d.ts +7 -0
  126. package/dist/storage.d.ts.map +1 -0
  127. package/dist/storage.js +6 -0
  128. package/dist/storage.js.map +1 -0
  129. package/dist/types.d.ts +438 -0
  130. package/dist/types.d.ts.map +1 -0
  131. package/dist/types.js +12 -0
  132. package/dist/types.js.map +1 -0
  133. package/dist/validation.d.ts +22 -0
  134. package/dist/validation.d.ts.map +1 -0
  135. package/dist/validation.js +12 -0
  136. package/dist/validation.js.map +1 -0
  137. package/dist/version-transport.d.ts +13 -0
  138. package/dist/version-transport.d.ts.map +1 -0
  139. package/dist/version-transport.js +26 -0
  140. package/dist/version-transport.js.map +1 -0
  141. package/dist/versioning.d.ts +48 -0
  142. package/dist/versioning.d.ts.map +1 -0
  143. package/dist/versioning.js +62 -0
  144. package/dist/versioning.js.map +1 -0
  145. package/package.json +84 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Storage adapters for the OKF engine.
3
+ *
4
+ * The engine's disk-facing operations are expressed against {@link StorageBackend}
5
+ * (declared in `types.ts`) so the store is PLUGGABLE. This module ships the DEFAULT
6
+ * adapter — {@link FilesystemBackend} — which wraps the local filesystem: a bundle
7
+ * is a directory tree of UTF-8 markdown files, written atomically (temp file +
8
+ * rename). It is the DEGENERATE case of the seam's hard contract: `version` is the
9
+ * SHA of the on-disk bytes, and `versions()` reports only the single current
10
+ * revision because a plain filesystem keeps no history. Compare-and-swap is
11
+ * serialized per logical identity across processes by a private runtime lock directory;
12
+ * a process-local promise queue avoids filesystem polling among callers in one process.
13
+ * `MemoryBackend`
14
+ * (`memory-backend.ts`) implements the SAME contract for the hard case; a remote
15
+ * (HTTP/CF/D1) adapter is a FUTURE plug-in, never a rewrite of the engine.
16
+ *
17
+ * This adapter touches no filesystem API itself. Every read and write goes through the
18
+ * exact-identity protocol in `filesystem-identity.ts` with its production port, which is what
19
+ * keeps two differently spelled ids from ever reaching one physical file on a case- or
20
+ * normalization-insensitive filesystem.
21
+ *
22
+ * There is exactly ONE frontmatter parser (`frontmatter.ts`); this adapter uses it.
23
+ * A remote backend that stores already-structured documents need not parse markdown
24
+ * at all — parsing is an implementation detail of THIS adapter, not of the seam.
25
+ */
26
+ import type { BlobKey, ConceptId, DeleteOptions, OkfDocument, ReadBlobResult, ReadResult, ReservedFilename, ReservedReadResult, StorageBackend, Version, VersionInfo, WriteOptions } from "./types.js";
27
+ /**
28
+ * The default {@link StorageBackend}: a filesystem-backed OKF bundle rooted at an
29
+ * absolute directory. Concept documents are markdown files at `<id>.md`; reserved
30
+ * files live at `<dir>/index.md` and `<dir>/log.md`.
31
+ */
32
+ export declare class FilesystemBackend implements StorageBackend {
33
+ #private;
34
+ /**
35
+ * The root is resolved once here: a relative root would otherwise re-resolve against the
36
+ * process's current directory on every operation, so a later `chdir` would silently move the
37
+ * bundle and derive a different identity key.
38
+ */
39
+ constructor(root: string);
40
+ read(id: ConceptId): Promise<ReadResult>;
41
+ readMany(ids: ConceptId[]): Promise<ReadResult[]>;
42
+ write(id: ConceptId, doc: OkfDocument, options?: WriteOptions): Promise<Version>;
43
+ delete(id: ConceptId, options?: DeleteOptions): Promise<boolean>;
44
+ versions(id: ConceptId): Promise<VersionInfo[]>;
45
+ exists(id: ConceptId): Promise<boolean>;
46
+ list(prefix?: string): Promise<ConceptId[]>;
47
+ readReserved(dir: string, name: ReservedFilename): Promise<ReservedReadResult | null>;
48
+ writeReserved(dir: string, name: ReservedFilename, content: string, options?: WriteOptions): Promise<Version>;
49
+ readBlob(key: BlobKey): Promise<ReadBlobResult | null>;
50
+ writeBlob(key: BlobKey, bytes: Uint8Array, _contentType?: string, options?: WriteOptions): Promise<Version>;
51
+ deleteBlob(key: BlobKey, options?: DeleteOptions): Promise<boolean>;
52
+ existsBlob(key: BlobKey): Promise<boolean>;
53
+ listBlobs(prefix?: string): Promise<BlobKey[]>;
54
+ capabilities(): {
55
+ readonly history: false;
56
+ readonly enforced_cas: true;
57
+ readonly blobs: true;
58
+ readonly projections: true;
59
+ readonly backlinks: false;
60
+ };
61
+ }
62
+ /** Internal exact-byte authority for the publication adapter; not part of StorageBackend. */
63
+ export declare function readRawFilesystemDocument(backend: FilesystemBackend, id: ConceptId): Promise<{
64
+ bytes: Uint8Array;
65
+ version: Version;
66
+ }>;
67
+ /** Internal exact-byte authority for reserved publication objects. */
68
+ export declare function readRawFilesystemReserved(backend: FilesystemBackend, dir: string, name: ReservedFilename): Promise<{
69
+ bytes: Uint8Array;
70
+ version: Version;
71
+ } | null>;
72
+ /** Internal canonical inventory of reserved publication objects. */
73
+ export declare function listFilesystemReservedObjects(backend: FilesystemBackend): Promise<Array<{
74
+ dir: string;
75
+ name: ReservedFilename;
76
+ }>>;
77
+ //# sourceMappingURL=backend.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.d.ts","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAyBH,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,aAAa,EACb,WAAW,EACX,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,OAAO,EACP,WAAW,EACX,YAAY,EACb,MAAM,YAAY,CAAC;AAqEpB;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,cAAc;;IAGtD;;;;OAIG;gBACS,IAAI,EAAE,MAAM;IAKlB,IAAI,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC;IAUxC,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAWjD,KAAK,CAAC,EAAE,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,OAAO,GAAE,YAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IA0BpF,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBpE,QAAQ,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA6B/C,MAAM,CAAC,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IAKvC,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IAmB3C,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAUrF,aAAa,CACjB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,gBAAgB,EACtB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,OAAO,CAAC;IAoBb,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAatD,SAAS,CACb,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,YAAY,CAAC,EAAE,MAAM,EACrB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,OAAO,CAAC;IAuBb,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAcvE,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAU1C,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAWpD,YAAY;;;;;;;CASb;AAQD,6FAA6F;AAC7F,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,iBAAiB,EAC1B,EAAE,EAAE,SAAS,GACZ,OAAO,CAAC;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAQlD;AAED,sEAAsE;AACtE,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,iBAAiB,EAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,CAAC,CASzD;AAED,oEAAoE;AACpE,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,KAAK,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,CAAC,CAAC,CAYzD"}
@@ -0,0 +1,380 @@
1
+ /**
2
+ * Storage adapters for the OKF engine.
3
+ *
4
+ * The engine's disk-facing operations are expressed against {@link StorageBackend}
5
+ * (declared in `types.ts`) so the store is PLUGGABLE. This module ships the DEFAULT
6
+ * adapter — {@link FilesystemBackend} — which wraps the local filesystem: a bundle
7
+ * is a directory tree of UTF-8 markdown files, written atomically (temp file +
8
+ * rename). It is the DEGENERATE case of the seam's hard contract: `version` is the
9
+ * SHA of the on-disk bytes, and `versions()` reports only the single current
10
+ * revision because a plain filesystem keeps no history. Compare-and-swap is
11
+ * serialized per logical identity across processes by a private runtime lock directory;
12
+ * a process-local promise queue avoids filesystem polling among callers in one process.
13
+ * `MemoryBackend`
14
+ * (`memory-backend.ts`) implements the SAME contract for the hard case; a remote
15
+ * (HTTP/CF/D1) adapter is a FUTURE plug-in, never a rewrite of the engine.
16
+ *
17
+ * This adapter touches no filesystem API itself. Every read and write goes through the
18
+ * exact-identity protocol in `filesystem-identity.ts` with its production port, which is what
19
+ * keeps two differently spelled ids from ever reaching one physical file on a case- or
20
+ * normalization-insensitive filesystem.
21
+ *
22
+ * There is exactly ONE frontmatter parser (`frontmatter.ts`); this adapter uses it.
23
+ * A remote backend that stores already-structured documents need not parse markdown
24
+ * at all — parsing is an implementation detail of THIS adapter, not of the seam.
25
+ */
26
+ import path from "node:path";
27
+ import { parseMarkdown, stringifyDoc } from "./frontmatter.js";
28
+ import { resolveContentType } from "./content-type.js";
29
+ import { assertSafeBlobKey, assertSafeConceptId, assertSafeReservedDir, conceptIdFromPath, isReservedFile, pathFromConceptId, toPosix, } from "./paths.js";
30
+ import { InvalidInputError } from "./errors.js";
31
+ import { mutateExact, nodeFilesystemIdentityPort as port, observeExact, probeExact, } from "./filesystem-identity.js";
32
+ import { mutationActorFromFrontmatter } from "./mutation-attribution.js";
33
+ import { blobVersion, defaultActor, VersionConflict, versionOfBytes } from "./versioning.js";
34
+ const publicationRoots = new WeakMap();
35
+ /** First trimmed non-empty string among `vals`, else `undefined`. */
36
+ function firstString(...vals) {
37
+ for (const v of vals) {
38
+ if (typeof v === "string" && v.trim() !== "")
39
+ return v;
40
+ }
41
+ return undefined;
42
+ }
43
+ /**
44
+ * True when a thrown fs error means "there is no FILE at this path" — absence (`ENOENT`,
45
+ * `ENOTDIR`) or a directory sitting where a file was expected (`EISDIR`, the blob-key/directory
46
+ * collision). Anything else (`EACCES`, `EPERM`, a disk error, …) is a REAL failure, not a "this
47
+ * blob doesn't exist" signal, and must propagate — a blanket catch that mapped every error to
48
+ * `null` would silently misreport a permissions problem as "absent."
49
+ */
50
+ function isAbsentFileError(err) {
51
+ const code = err?.code;
52
+ return code === "ENOENT" || code === "ENOTDIR" || code === "EISDIR";
53
+ }
54
+ /** The ENOENT-shaped rejection `read`/`readMany` promise for an absent document. */
55
+ function notFound(root, rel) {
56
+ const target = path.join(root, rel);
57
+ const err = new Error(`ENOENT: no such file or directory, open '${target}'`);
58
+ err.code = "ENOENT";
59
+ err.syscall = "open";
60
+ err.path = target;
61
+ return err;
62
+ }
63
+ /** Observation read: every byte through the open handle; `null` when no file is there. */
64
+ async function readBytes(handle) {
65
+ try {
66
+ return await port.readAll(handle);
67
+ }
68
+ catch (err) {
69
+ if (isAbsentFileError(err))
70
+ return null;
71
+ throw err;
72
+ }
73
+ }
74
+ /** Recursively collect bundle-relative posix paths of files `keep` accepts (skips dot-entries). */
75
+ async function walkFiles(root, keep, sub = "") {
76
+ const entries = (await port.entries(path.join(root, sub))) ?? [];
77
+ const out = [];
78
+ for (const entry of entries) {
79
+ if (entry.name.startsWith("."))
80
+ continue; // .git, temp files, dot-dirs: invisible to the walk
81
+ const rel = sub === "" ? entry.name : `${sub}/${entry.name}`;
82
+ if (entry.kind === "directory") {
83
+ out.push(...(await walkFiles(root, keep, rel)));
84
+ }
85
+ else if (entry.kind === "file" && keep(entry.name)) {
86
+ // `rel` is already assembled with `/`. Preserve any literal backslash in an entry name so
87
+ // `list()` can reject it as a noncanonical on-disk identity instead of silently converting
88
+ // it into a different nested concept id.
89
+ out.push(rel);
90
+ }
91
+ }
92
+ return out;
93
+ }
94
+ /** Bundle-relative reserved-file path for a directory (`""` = bundle root). */
95
+ function reservedPath(dir, name) {
96
+ const d = toPosix(dir).replace(/^\.?\//, "").replace(/\/$/, "");
97
+ return d === "" ? name : `${d}/${name}`;
98
+ }
99
+ /**
100
+ * The default {@link StorageBackend}: a filesystem-backed OKF bundle rooted at an
101
+ * absolute directory. Concept documents are markdown files at `<id>.md`; reserved
102
+ * files live at `<dir>/index.md` and `<dir>/log.md`.
103
+ */
104
+ export class FilesystemBackend {
105
+ #root;
106
+ /**
107
+ * The root is resolved once here: a relative root would otherwise re-resolve against the
108
+ * process's current directory on every operation, so a later `chdir` would silently move the
109
+ * bundle and derive a different identity key.
110
+ */
111
+ constructor(root) {
112
+ this.#root = path.resolve(root);
113
+ publicationRoots.set(this, this.#root);
114
+ }
115
+ async read(id) {
116
+ assertSafeConceptId(id);
117
+ const rel = pathFromConceptId(id);
118
+ const observed = await observeExact(port, this.#root, rel, readBytes);
119
+ if (observed.state === "absent")
120
+ throw notFound(this.#root, rel);
121
+ const raw = observed.value.toString("utf8");
122
+ const { frontmatter, body } = parseMarkdown(raw, rel);
123
+ return { doc: { id, frontmatter, body }, version: versionOfBytes(raw) };
124
+ }
125
+ async readMany(ids) {
126
+ // Validate every id BEFORE any path realization (not just the first that `read`
127
+ // would hit) — degenerate batch read: a loop of single reads, since a local
128
+ // filesystem has no per-read round-trip to amortize. A networked backend implements
129
+ // this as one multi-get, which is the whole reason `readMany` is on the seam.
130
+ for (const id of ids)
131
+ assertSafeConceptId(id);
132
+ const out = [];
133
+ for (const id of ids)
134
+ out.push(await this.read(id));
135
+ return out;
136
+ }
137
+ async write(id, doc, options = {}) {
138
+ assertSafeConceptId(id);
139
+ const raw = stringifyDoc(doc.frontmatter, doc.body ?? "");
140
+ const rel = pathFromConceptId(id);
141
+ // The whole check-then-write section runs inside one identity-keyed critical section, local
142
+ // and same-user cross-process; an unconditional writer holds it too so it cannot move the
143
+ // target between another process's version check and write.
144
+ return mutateExact(port, this.#root, rel, async (target) => {
145
+ if (options.expectedVersion !== undefined) {
146
+ const bytes = await target.current();
147
+ const current = bytes === null ? null : versionOfBytes(bytes.toString("utf8"));
148
+ if (current !== options.expectedVersion) {
149
+ throw new VersionConflict(id, options.expectedVersion, current);
150
+ }
151
+ }
152
+ // `options.actor` is accepted for contract parity but NOT persisted here: the
153
+ // filesystem keeps no history, and stamping it into frontmatter would both change
154
+ // existing CLI output and diverge the document from other backends. `versions()`
155
+ // reports actor from the portable mutation-attribution projection if present, else a
156
+ // local default — an honest degenerate answer. `options.agent` is likewise
157
+ // accepted-but-not-persisted (this degenerate adapter records no agent at all).
158
+ await target.replace(Buffer.from(raw, "utf8"));
159
+ return versionOfBytes(raw);
160
+ });
161
+ }
162
+ async delete(id, options = {}) {
163
+ assertSafeConceptId(id);
164
+ return mutateExact(port, this.#root, pathFromConceptId(id), async (target) => {
165
+ const bytes = await target.current();
166
+ if (bytes === null)
167
+ return false; // absent ⇒ idempotent no-op, EVEN under CAS
168
+ const current = versionOfBytes(bytes.toString("utf8"));
169
+ if (options.expectedVersion !== undefined && current !== options.expectedVersion) {
170
+ throw new VersionConflict(id, options.expectedVersion, current);
171
+ }
172
+ await target.remove();
173
+ // Empty parent dirs are intentionally NOT pruned (a write never prunes either) — a later
174
+ // write to a sibling id under the same now-empty directory must not have to worry about
175
+ // a missing directory tree.
176
+ return true;
177
+ });
178
+ }
179
+ async versions(id) {
180
+ assertSafeConceptId(id);
181
+ const rel = pathFromConceptId(id);
182
+ const observed = await observeExact(port, this.#root, rel, async (handle, target) => {
183
+ try {
184
+ const bytes = await port.readAll(handle);
185
+ // mtime is taken by path rather than through the open handle: the port has no
186
+ // stat-by-handle call, and widening the protocol surface for a fallback timestamp used
187
+ // only when the frontmatter carries none is not worth it. It cannot attribute another
188
+ // entry's mtime to this identity: the post-walk that follows requires the leaf the
189
+ // requested path reaches to still be this handle's inode and every directory segment to
190
+ // still be its recorded one, so a swap between this call and that check restarts the
191
+ // observation instead of returning EXACT — under the same A11 witness limit the walk
192
+ // itself carries.
193
+ const { mtime } = await port.stat(target);
194
+ return { raw: bytes.toString("utf8"), mtime };
195
+ }
196
+ catch {
197
+ return null; // no readable document ⇒ no history
198
+ }
199
+ });
200
+ if (observed.state === "absent")
201
+ return [];
202
+ const { raw, mtime } = observed.value;
203
+ const { frontmatter } = parseMarkdown(raw, rel);
204
+ const actor = mutationActorFromFrontmatter(frontmatter) ?? defaultActor();
205
+ const timestamp = firstString(frontmatter.timestamp) ?? mtime.toISOString();
206
+ // Single current revision: a plain filesystem retains no prior versions.
207
+ return [{ version: versionOfBytes(raw), actor, timestamp }];
208
+ }
209
+ async exists(id) {
210
+ assertSafeConceptId(id);
211
+ return (await probeExact(port, this.#root, pathFromConceptId(id))).state === "exact";
212
+ }
213
+ async list(prefix) {
214
+ const files = await walkFiles(this.#root, (name) => name.endsWith(".md"));
215
+ const ids = [];
216
+ for (const rel of files) {
217
+ if (isReservedFile(rel))
218
+ continue;
219
+ const id = conceptIdFromPath(rel);
220
+ assertSafeConceptId(id);
221
+ if (pathFromConceptId(id) !== rel) {
222
+ throw new InvalidInputError(`Concept path '${rel}' does not round-trip through canonical id '${id}'. Rename the file to '${pathFromConceptId(id)}'.`);
223
+ }
224
+ if (prefix && !id.startsWith(prefix))
225
+ continue;
226
+ ids.push(id);
227
+ }
228
+ ids.sort((a, b) => a.localeCompare(b));
229
+ return ids;
230
+ }
231
+ async readReserved(dir, name) {
232
+ assertSafeReservedDir(dir);
233
+ const observed = await observeExact(port, this.#root, reservedPath(dir, name), readBytes);
234
+ if (observed.state === "absent")
235
+ return null;
236
+ const content = observed.value.toString("utf8");
237
+ // Reserved files are unparsed markdown, so the version is the content-address of the
238
+ // raw bytes — the same digest a concept document's on-disk bytes carry.
239
+ return { content, version: versionOfBytes(content) };
240
+ }
241
+ async writeReserved(dir, name, content, options = {}) {
242
+ assertSafeReservedDir(dir);
243
+ const rel = reservedPath(dir, name);
244
+ // Same identity-keyed critical section as `write()`. A reserved-file read-modify-write
245
+ // depends on a genuine `VersionConflict` under contention.
246
+ return mutateExact(port, this.#root, rel, async (target) => {
247
+ if (options.expectedVersion !== undefined) {
248
+ const bytes = await target.current();
249
+ const current = bytes === null ? null : versionOfBytes(bytes.toString("utf8"));
250
+ if (current !== options.expectedVersion) {
251
+ throw new VersionConflict(rel, options.expectedVersion, current);
252
+ }
253
+ }
254
+ await target.replace(Buffer.from(content, "utf8"));
255
+ return versionOfBytes(content);
256
+ });
257
+ }
258
+ // ── blobs: opaque bytes + a content-type ──────────────────────────────────
259
+ async readBlob(key) {
260
+ assertSafeBlobKey(key);
261
+ // Absence (ENOENT) or a directory sitting at this path (EISDIR) is a normal "no blob here"
262
+ // result; `readBytes` propagates everything else (EACCES, EPERM, …) as the real failure it is.
263
+ const observed = await observeExact(port, this.#root, key, readBytes);
264
+ if (observed.state === "absent")
265
+ return null;
266
+ const bytes = observed.value; // raw bytes, NO encoding (B1)
267
+ // Content-type is ALWAYS inferred-on-read here: the filesystem adapter accepts but
268
+ // does not persist an explicit override at write time (see writeBlob's doc comment,
269
+ // B5) — there is no sidecar to read it back from.
270
+ return { bytes, contentType: resolveContentType(key), version: blobVersion(bytes) };
271
+ }
272
+ async writeBlob(key, bytes, _contentType, options = {}) {
273
+ assertSafeBlobKey(key);
274
+ // The WHOLE check-then-write section runs inside the identity lock, exactly like write(),
275
+ // so N concurrent CAS writers to the SAME blob key queue instead of racing the version
276
+ // check (B3). Raw-bytes versioning: hashing through a UTF-8 decode would corrupt binary (B1).
277
+ return mutateExact(port, this.#root, key, async (target) => {
278
+ if (options.expectedVersion !== undefined) {
279
+ const existing = await target.current();
280
+ const current = existing === null ? null : blobVersion(existing);
281
+ if (current !== options.expectedVersion) {
282
+ throw new VersionConflict(key, options.expectedVersion, current);
283
+ }
284
+ }
285
+ // `contentType` (like `options.actor`) is accepted for contract parity but NOT
286
+ // persisted here: the filesystem keeps no sidecar metadata store, so an explicit
287
+ // override is honored at write time and re-inferred from the key extension on
288
+ // every read instead (see readBlob) — mirrors write()'s actor-parity posture
289
+ // exactly (B5). `MemoryBackend` persists it because it keeps state.
290
+ await target.replace(bytes);
291
+ return blobVersion(bytes);
292
+ });
293
+ }
294
+ async deleteBlob(key, options = {}) {
295
+ assertSafeBlobKey(key);
296
+ return mutateExact(port, this.#root, key, async (target) => {
297
+ const existing = await target.current();
298
+ if (existing === null)
299
+ return false; // absent (or a directory-shaped path) ⇒ idempotent no-op
300
+ const current = blobVersion(existing);
301
+ if (options.expectedVersion !== undefined && current !== options.expectedVersion) {
302
+ throw new VersionConflict(key, options.expectedVersion, current);
303
+ }
304
+ await target.remove();
305
+ return true;
306
+ });
307
+ }
308
+ async existsBlob(key) {
309
+ assertSafeBlobKey(key);
310
+ // A regular file only: a blob key that collides with an existing DIRECTORY (e.g. a sibling
311
+ // key like `artifacts/x/y.bin` leaves `artifacts/x` a directory) must report `false` here,
312
+ // matching MemoryBackend/RemoteBackend — neither has a filesystem notion of "a path that is
313
+ // a directory," so a directory-counts-as-exists answer would break tri-adapter parity.
314
+ const observed = await probeExact(port, this.#root, key);
315
+ return observed.state === "exact" && observed.value.kind === "file";
316
+ }
317
+ async listBlobs(prefix) {
318
+ // Skipping dot-entries is what excludes the adapter's own dot-prefixed temp files and `.git`
319
+ // from a blob listing (I3), not just the write-time `assertSafeBlobKey` guard. The
320
+ // `.md`-extension check is case-insensitive, mirroring `assertSafeBlobKey`.
321
+ const files = await walkFiles(this.#root, (name) => !name.toLowerCase().endsWith(".md"));
322
+ const keys = files.map(toPosix);
323
+ const filtered = prefix ? keys.filter((k) => k.startsWith(prefix)) : keys;
324
+ filtered.sort((a, b) => a.localeCompare(b));
325
+ return filtered;
326
+ }
327
+ capabilities() {
328
+ return {
329
+ history: false,
330
+ enforced_cas: true,
331
+ blobs: true,
332
+ projections: true,
333
+ backlinks: false,
334
+ };
335
+ }
336
+ }
337
+ function publicationRoot(backend) {
338
+ const root = publicationRoots.get(backend);
339
+ if (!root)
340
+ throw new InvalidInputError("Unknown filesystem backend publication source.");
341
+ return root;
342
+ }
343
+ /** Internal exact-byte authority for the publication adapter; not part of StorageBackend. */
344
+ export async function readRawFilesystemDocument(backend, id) {
345
+ assertSafeConceptId(id);
346
+ const root = publicationRoot(backend);
347
+ const rel = pathFromConceptId(id);
348
+ const observed = await observeExact(port, root, rel, readBytes);
349
+ if (observed.state === "absent")
350
+ throw notFound(root, rel);
351
+ const raw = new TextDecoder("utf-8", { fatal: true }).decode(observed.value);
352
+ return { bytes: observed.value.slice(), version: versionOfBytes(raw) };
353
+ }
354
+ /** Internal exact-byte authority for reserved publication objects. */
355
+ export async function readRawFilesystemReserved(backend, dir, name) {
356
+ assertSafeReservedDir(dir);
357
+ const root = publicationRoot(backend);
358
+ const observed = await observeExact(port, root, reservedPath(dir, name), readBytes);
359
+ if (observed.state === "absent")
360
+ return null;
361
+ return {
362
+ bytes: observed.value.slice(),
363
+ version: versionOfBytes(observed.value.toString("utf8")),
364
+ };
365
+ }
366
+ /** Internal canonical inventory of reserved publication objects. */
367
+ export async function listFilesystemReservedObjects(backend) {
368
+ const root = publicationRoot(backend);
369
+ const files = await walkFiles(root, (name) => name === "index.md" || name === "log.md");
370
+ return files
371
+ .map((relative) => {
372
+ const slash = relative.lastIndexOf("/");
373
+ const dir = slash === -1 ? "" : relative.slice(0, slash);
374
+ const name = relative.slice(slash + 1);
375
+ assertSafeReservedDir(dir);
376
+ return { dir, name };
377
+ })
378
+ .sort((a, b) => reservedPath(a.dir, a.name).localeCompare(reservedPath(b.dir, b.name)));
379
+ }
380
+ //# sourceMappingURL=backend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Legacy bundle-shaped core API.
3
+ *
4
+ * Portable semantics live in `engine.ts` and receive a backend explicitly. This adapter preserves
5
+ * the historical `{ root, backend? }` signatures and filesystem fallback used by Node consumers.
6
+ */
7
+ import * as engine from "./engine.js";
8
+ import type { BlobKey, Bundle, ConceptId, DeleteOptions, EdgeFilter, HeadResult, InitBundleOptions, Link, OkfDocument, QueryFilter, ReadBlobResult, ReadResult, StorageBackend, Version, VersionInfo, WriteOptions } from "./types.js";
9
+ export { matchesFilter } from "./query-filter.js";
10
+ export type { QueryOptions, SkippedDoc, WriteResult } from "./engine.js";
11
+ /** Resolve the backend a legacy bundle operation should use. */
12
+ export declare function backendFor(bundle: Bundle): StorageBackend;
13
+ export declare function readBundleOkfVersion(bundle: Bundle): Promise<string | undefined>;
14
+ export declare const SUPPORTED_OKF_AUTHORING_VERSIONS: readonly ["0.1", "0.2"];
15
+ export declare const DEFAULT_OKF_AUTHORING_VERSION = "0.2";
16
+ export declare function resolveOkfAuthoringVersion(requested?: string): string;
17
+ /** Initialize or open a filesystem-backed bundle. */
18
+ export declare function initBundle(root: string, options?: InitBundleOptions): Promise<Bundle>;
19
+ export declare function writeDocVersioned(bundle: Bundle, doc: OkfDocument, options?: WriteOptions): Promise<engine.WriteResult>;
20
+ export declare function writeDocVersionedForEdition(bundle: Bundle, doc: OkfDocument, okfVersion: string, options?: WriteOptions): Promise<engine.WriteResult>;
21
+ export declare function writeDoc(bundle: Bundle, doc: OkfDocument, options?: WriteOptions): Promise<OkfDocument>;
22
+ export declare function readDocVersioned(bundle: Bundle, id: ConceptId): Promise<ReadResult>;
23
+ export declare function readDoc(bundle: Bundle, id: ConceptId): Promise<OkfDocument>;
24
+ export declare function existsDoc(bundle: Bundle, id: ConceptId): Promise<boolean>;
25
+ export declare function docVersions(bundle: Bundle, id: ConceptId): Promise<VersionInfo[]>;
26
+ export declare function deleteDoc(bundle: Bundle, id: ConceptId, options?: DeleteOptions): Promise<boolean>;
27
+ export declare function query(bundle: Bundle, filter?: QueryFilter, options?: engine.QueryOptions): Promise<OkfDocument[]>;
28
+ export declare const list: typeof query;
29
+ export declare function queryHeads(bundle: Bundle, filter?: QueryFilter, options?: engine.QueryOptions): Promise<HeadResult[]>;
30
+ export declare function parseLinks(_bundle: Bundle, doc: OkfDocument): Link[];
31
+ export declare function queryEdges(bundle: Bundle, filter?: EdgeFilter): Promise<Link[]>;
32
+ export declare function backlinks(bundle: Bundle, target: ConceptId): Promise<Link[]>;
33
+ export declare function readBlob(bundle: Bundle, key: BlobKey): Promise<ReadBlobResult | null>;
34
+ export declare function writeBlob(bundle: Bundle, key: BlobKey, bytes: Uint8Array, contentType?: string, options?: WriteOptions): Promise<Version>;
35
+ export declare function existsBlob(bundle: Bundle, key: BlobKey): Promise<boolean>;
36
+ export declare function listBlobs(bundle: Bundle, prefix?: string): Promise<BlobKey[]>;
37
+ export declare function deleteBlob(bundle: Bundle, key: BlobKey, options?: DeleteOptions): Promise<boolean>;
38
+ //# sourceMappingURL=bundle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle.d.ts","sourceRoot":"","sources":["../src/bundle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAKtC,OAAO,KAAK,EACV,OAAO,EACP,MAAM,EACN,SAAS,EACT,aAAa,EACb,UAAU,EACV,UAAU,EACV,iBAAiB,EACjB,IAAI,EACJ,WAAW,EACX,WAAW,EACX,cAAc,EACd,UAAU,EACV,cAAc,EACd,OAAO,EACP,WAAW,EACX,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEzE,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAEzD;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAEtF;AAED,eAAO,MAAM,gCAAgC,yBAA0B,CAAC;AACxE,eAAO,MAAM,6BAA6B,QAAQ,CAAC;AAEnD,wBAAgB,0BAA0B,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CASrE;AAED,qDAAqD;AACrD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAgB/F;AAED,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAE7B;AAED,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,WAAW,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,CAE7B;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,WAAW,EAChB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAEzF;AAED,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,CAEjF;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,CAE/E;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAEvF;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAExG;AAED,wBAAsB,KAAK,CACzB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,WAAgB,EACxB,OAAO,GAAE,MAAM,CAAC,YAAiB,GAChC,OAAO,CAAC,WAAW,EAAE,CAAC,CAExB;AAED,eAAO,MAAM,IAAI,cAAQ,CAAC;AAE1B,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,WAAgB,EACxB,OAAO,GAAE,MAAM,CAAC,YAAiB,GAChC,OAAO,CAAC,UAAU,EAAE,CAAC,CAEvB;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,GAAG,IAAI,EAAE,CAEpE;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAEzF;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,CAElF;AAED,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAE3F;AAED,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,UAAU,EACjB,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAE/E;AAED,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAEnF;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAExG"}
package/dist/bundle.js ADDED
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Legacy bundle-shaped core API.
3
+ *
4
+ * Portable semantics live in `engine.ts` and receive a backend explicitly. This adapter preserves
5
+ * the historical `{ root, backend? }` signatures and filesystem fallback used by Node consumers.
6
+ */
7
+ import path from "node:path";
8
+ import { FilesystemBackend } from "./backend.js";
9
+ import * as engine from "./engine.js";
10
+ import { InvalidInputError } from "./errors.js";
11
+ import { stringifyWithData } from "./frontmatter.js";
12
+ import { GENERATED_INDEX_MARKER } from "./index-marker.js";
13
+ import { VersionConflict } from "./versioning.js";
14
+ export { matchesFilter } from "./query-filter.js";
15
+ /** Resolve the backend a legacy bundle operation should use. */
16
+ export function backendFor(bundle) {
17
+ return bundle.backend ?? new FilesystemBackend(bundle.root);
18
+ }
19
+ export async function readBundleOkfVersion(bundle) {
20
+ return engine.readBundleOkfVersion(backendFor(bundle));
21
+ }
22
+ export const SUPPORTED_OKF_AUTHORING_VERSIONS = ["0.1", "0.2"];
23
+ export const DEFAULT_OKF_AUTHORING_VERSION = "0.2";
24
+ export function resolveOkfAuthoringVersion(requested) {
25
+ const version = requested ?? DEFAULT_OKF_AUTHORING_VERSION;
26
+ if (!SUPPORTED_OKF_AUTHORING_VERSIONS.includes(version)) {
27
+ throw new InvalidInputError(`Unsupported OKF authoring version '${version}'. This build can author ${SUPPORTED_OKF_AUTHORING_VERSIONS.join(" and ")}; ` +
28
+ "bundles declaring other versions can still be read or transported.");
29
+ }
30
+ return version;
31
+ }
32
+ /** Initialize or open a filesystem-backed bundle. */
33
+ export async function initBundle(root, options = {}) {
34
+ const okfVersion = resolveOkfAuthoringVersion(options.okfVersion);
35
+ const resolved = path.resolve(root);
36
+ const backend = new FilesystemBackend(resolved);
37
+ if (options.expectNew || (await backend.readReserved("", "index.md")) === null) {
38
+ const name = path.basename(resolved);
39
+ const body = `${GENERATED_INDEX_MARKER}\n# ${name}\n\nAn Open Knowledge Format bundle.\n`;
40
+ try {
41
+ await backend.writeReserved("", "index.md", stringifyWithData({ okf_version: okfVersion }, body), {
42
+ expectedVersion: null,
43
+ });
44
+ }
45
+ catch (err) {
46
+ if (options.expectNew || !(err instanceof VersionConflict))
47
+ throw err;
48
+ }
49
+ }
50
+ return { root: resolved };
51
+ }
52
+ export async function writeDocVersioned(bundle, doc, options) {
53
+ return engine.writeDocVersioned(backendFor(bundle), doc, options);
54
+ }
55
+ export async function writeDocVersionedForEdition(bundle, doc, okfVersion, options) {
56
+ return engine.writeDocVersionedForEdition(backendFor(bundle), doc, okfVersion, options);
57
+ }
58
+ export async function writeDoc(bundle, doc, options) {
59
+ return engine.writeDoc(backendFor(bundle), doc, options);
60
+ }
61
+ export async function readDocVersioned(bundle, id) {
62
+ return engine.readDocVersioned(backendFor(bundle), id);
63
+ }
64
+ export async function readDoc(bundle, id) {
65
+ return engine.readDoc(backendFor(bundle), id);
66
+ }
67
+ export async function existsDoc(bundle, id) {
68
+ return engine.existsDoc(backendFor(bundle), id);
69
+ }
70
+ export async function docVersions(bundle, id) {
71
+ return engine.docVersions(backendFor(bundle), id);
72
+ }
73
+ export async function deleteDoc(bundle, id, options) {
74
+ return engine.deleteDoc(backendFor(bundle), id, options);
75
+ }
76
+ export async function query(bundle, filter = {}, options = {}) {
77
+ return engine.query(backendFor(bundle), filter, options);
78
+ }
79
+ export const list = query;
80
+ export async function queryHeads(bundle, filter = {}, options = {}) {
81
+ return engine.queryHeads(backendFor(bundle), filter, options);
82
+ }
83
+ export function parseLinks(_bundle, doc) {
84
+ return engine.parseLinks(doc);
85
+ }
86
+ export async function queryEdges(bundle, filter = {}) {
87
+ return engine.queryEdges(backendFor(bundle), filter);
88
+ }
89
+ export async function backlinks(bundle, target) {
90
+ return engine.backlinks(backendFor(bundle), target);
91
+ }
92
+ export async function readBlob(bundle, key) {
93
+ return engine.readBlob(backendFor(bundle), key);
94
+ }
95
+ export async function writeBlob(bundle, key, bytes, contentType, options) {
96
+ return engine.writeBlob(backendFor(bundle), key, bytes, contentType, options);
97
+ }
98
+ export async function existsBlob(bundle, key) {
99
+ return engine.existsBlob(backendFor(bundle), key);
100
+ }
101
+ export async function listBlobs(bundle, prefix) {
102
+ return engine.listBlobs(backendFor(bundle), prefix);
103
+ }
104
+ export async function deleteBlob(bundle, key, options) {
105
+ return engine.deleteBlob(backendFor(bundle), key, options);
106
+ }
107
+ //# sourceMappingURL=bundle.js.map