@volter/world-core 3.0.154 → 3.0.156

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 (107) hide show
  1. package/dist/generated/pack-facts.json +140 -0
  2. package/dist/inject.cjs +150 -86
  3. package/dist/src/actions.d.ts +15 -0
  4. package/dist/src/actions.js +82 -21
  5. package/dist/src/ancestry.d.ts +5 -4
  6. package/dist/src/ancestry.js +53 -28
  7. package/dist/src/changeset.js +1 -1
  8. package/dist/src/clickhouse/compression.d.ts +28 -0
  9. package/dist/src/clickhouse/compression.js +281 -0
  10. package/dist/src/clickhouse/index.d.ts +1 -0
  11. package/dist/src/clickhouse/index.js +1 -0
  12. package/dist/src/client-bundle.js +15 -15
  13. package/dist/src/derived-core.d.ts +12 -1
  14. package/dist/src/derived-core.js +145 -11
  15. package/dist/src/derived.js +3 -0
  16. package/dist/src/fork.js +1 -1
  17. package/dist/src/graphql-wire.d.ts +5 -0
  18. package/dist/src/graphql-wire.js +6 -6
  19. package/dist/src/grpc-wire.js +2 -1
  20. package/dist/src/h2.js +63 -10
  21. package/dist/src/head.d.ts +3 -0
  22. package/dist/src/head.js +9 -0
  23. package/dist/src/history.d.ts +1 -1
  24. package/dist/src/history.js +7 -7
  25. package/dist/src/index.d.ts +4 -1
  26. package/dist/src/index.js +5 -1
  27. package/dist/src/log.d.ts +23 -3
  28. package/dist/src/log.js +160 -37
  29. package/dist/src/managed-original-inputs.d.ts +101 -0
  30. package/dist/src/managed-original-inputs.js +125 -0
  31. package/dist/src/mongodb/client.d.ts +8 -0
  32. package/dist/src/mongodb/client.js +27 -0
  33. package/dist/src/mongodb/index.d.ts +2 -0
  34. package/dist/src/mongodb/index.js +5 -0
  35. package/dist/src/mongodb/stream.d.ts +74 -0
  36. package/dist/src/mongodb/stream.js +206 -0
  37. package/dist/src/observe.js +1 -1
  38. package/dist/src/pack-fetch.d.ts +2 -1
  39. package/dist/src/pack-fetch.js +21 -9
  40. package/dist/src/packRegistry.d.ts +10 -14
  41. package/dist/src/packRegistry.js +2 -13
  42. package/dist/src/protocol.d.ts +13 -0
  43. package/dist/src/protocol.js +13 -0
  44. package/dist/src/redis/engine.d.ts +10 -4
  45. package/dist/src/redis/engine.js +103 -32
  46. package/dist/src/redis/member-storage.js +20 -8
  47. package/dist/src/redis/service-times.d.ts +25 -0
  48. package/dist/src/redis/service-times.js +87 -0
  49. package/dist/src/redis/stream.d.ts +2 -1
  50. package/dist/src/redis/stream.js +109 -20
  51. package/dist/src/runtime-state.d.ts +11 -0
  52. package/dist/src/runtime-state.js +13 -0
  53. package/dist/src/runtime.d.ts +4 -2
  54. package/dist/src/runtime.js +5 -2
  55. package/dist/src/serve-http.d.ts +2 -0
  56. package/dist/src/serve-http.js +21 -4
  57. package/dist/src/serve.d.ts +10 -0
  58. package/dist/src/serve.js +43 -3
  59. package/dist/src/storage.d.ts +2 -1
  60. package/dist/src/storage.js +6 -3
  61. package/dist/src/world-boot.d.ts +1 -0
  62. package/dist/src/world-boot.js +6 -0
  63. package/dist/src/world-clock.js +6 -2
  64. package/dist/src/world-store.d.ts +108 -7
  65. package/dist/src/world-store.js +883 -103
  66. package/dist/src/xml.d.ts +30 -0
  67. package/dist/src/xml.js +74 -0
  68. package/generated/pack-facts.json +140 -0
  69. package/inject.cjs +150 -86
  70. package/package.json +20 -1
  71. package/src/actions.ts +78 -21
  72. package/src/ancestry.ts +46 -24
  73. package/src/changeset.ts +1 -1
  74. package/src/clickhouse/compression.ts +172 -0
  75. package/src/clickhouse/index.ts +2 -0
  76. package/src/client-bundle.ts +13 -14
  77. package/src/derived-core.ts +142 -11
  78. package/src/derived.ts +3 -0
  79. package/src/fork.ts +1 -1
  80. package/src/graphql-wire.ts +9 -6
  81. package/src/grpc-wire.ts +2 -1
  82. package/src/h2.ts +46 -5
  83. package/src/head.ts +9 -0
  84. package/src/history.ts +7 -7
  85. package/src/index.ts +6 -1
  86. package/src/log.ts +147 -32
  87. package/src/managed-original-inputs.ts +163 -0
  88. package/src/mongodb/client.ts +27 -0
  89. package/src/mongodb/index.ts +5 -0
  90. package/src/mongodb/stream.ts +213 -0
  91. package/src/observe.ts +1 -1
  92. package/src/pack-fetch.ts +23 -11
  93. package/src/packRegistry.ts +3 -15
  94. package/src/protocol.ts +13 -0
  95. package/src/redis/engine.ts +100 -57
  96. package/src/redis/member-storage.ts +17 -9
  97. package/src/redis/service-times.ts +81 -0
  98. package/src/redis/stream.ts +66 -14
  99. package/src/runtime-state.ts +14 -0
  100. package/src/runtime.ts +6 -1
  101. package/src/serve-http.ts +23 -4
  102. package/src/serve.ts +45 -3
  103. package/src/storage.ts +5 -3
  104. package/src/world-boot.ts +6 -0
  105. package/src/world-clock.ts +6 -2
  106. package/src/world-store.ts +704 -91
  107. package/src/xml.ts +71 -0
@@ -7,6 +7,17 @@ export type WorldStat = {
7
7
  isDirectory: boolean;
8
8
  isSymbolicLink?: boolean;
9
9
  };
10
+ /** Diagnostic context only; it does not change lock acquisition or stale-owner policy. */
11
+ export type WorldLockOptions = {
12
+ retainLiveOwner?: boolean;
13
+ operation?: string;
14
+ caller?: string;
15
+ };
16
+ /** Capture at the outermost lock helper, then carry the same caller through nested helpers. */
17
+ export declare function storageLockScope(options?: WorldLockOptions): WorldLockOptions & {
18
+ operation: string;
19
+ caller: string;
20
+ };
10
21
  /**
11
22
  * The synchronous persistence seam. Every path is an ABSOLUTE key the caller already
12
23
  * computed (via `worldPaths`/`worldStateRoot`); the store treats it as an opaque key,
@@ -51,13 +62,57 @@ export interface WorldStore {
51
62
  readRange?(path: string, start: number): string | null;
52
63
  /** Resolve filesystem aliases for durable ownership; absent on opaque-key stores. */
53
64
  canonicalPath?(path: string): string;
65
+ /** `read`, for a small file every operation needs and few change (a branch's pointer, the World's clock): the text
66
+ * kept from the last read while the path's own facts stand, so an unchanged file costs one check and no read.
67
+ * Optional: a store without it is read. */
68
+ readKept?(path: string): string | null;
69
+ /** The facts of the generation kept beside a tree's files in `dirPath` (TREE_FILES): one string that differs after
70
+ * any write of one of them through a store, by this process or another; `null` where the directory has none yet,
71
+ * which says nothing. Optional: a store without it is asked for each file's own facts. */
72
+ generation?(dirPath: string): string | null;
73
+ /** The generation in `dirPath` now, when exactly one write of a tree's file through a store has moved it since
74
+ * `before` (a generation this store answered for it); `null` when it cannot say so. A writer that read `before` just
75
+ * ahead of its own write, holding the directory's history lock, learns that its write was the only one (log.ts
76
+ * appendToBranchLog). Optional, beside `generation`. */
77
+ generationAfterOwnWrite?(dirPath: string, before: string): string | null;
54
78
  /** Run `fn` holding an exclusive lock on `lockPath`, releasing it afterwards. The fs
55
79
  * backend uses the historical cross-process reclaimable file lock; an in-memory,
56
80
  * single-instance backend is a synchronous pass-through. */
57
- withLock<T>(lockPath: string, fn: () => T, options?: {
58
- retainLiveOwner?: boolean;
59
- }): T;
81
+ withLock<T>(lockPath: string, fn: () => T, options?: WorldLockOptions): T;
60
82
  }
83
+ /** The files a service's tree is folded from, by name in its state directory (log.ts: the parent log, the branch log,
84
+ * the branch's pointer), and the generation a store keeps beside them. */
85
+ export declare const TREE_FILES: {
86
+ readonly parent: "events.jsonl";
87
+ readonly branch: "actions.jsonl";
88
+ readonly pointer: "branch.json";
89
+ };
90
+ export declare const TREE_GENERATION = "tree.generation";
91
+ /**
92
+ * A WORLD'S CARRIED LOCKS, REMOVED AT ITS OPEN (S2 K4). A World booted over its kept state (`up --keep-state`, a
93
+ * tab's restored archive) carries whatever lock files its last life left in its services' state directories. One whose
94
+ * holder record cannot be read is no holder's once its taker has gone, and a restore gives it the restore's file time,
95
+ * so the empty-record grace and the 60 s age ran from the restore: every waiter waited them, or gave up at 10 s (Twenty
96
+ * e946aa4c run 2: anthropic's projection.lock, "holder record unreadable", 10,086 ms, then its credentials 500 and the
97
+ * server 10 s late). A carried `.recovery` that is not empty and does not parse was never ended by R13's rule at all.
98
+ *
99
+ * A file is carried only when all of these hold: it is a world-core lock or its reclaim record (`*.lock`,
100
+ * `*.lock.recovery`) in a service's state directory (`<root>/<service>/<stateDir>/world`, never a yarn.lock or any
101
+ * project file); its text is empty or a holder record's beginning (`{"pid"`) that does not parse; and its file time is
102
+ * before `before`, the start of this boot's claim. A restore sets the time before the claim; a taker that is live now
103
+ * (a CLI's changeset rebase, a branch World keeping this one as its parent's storage, a two-call taker between its
104
+ * create and its record) made its file after it. Each removal is still a reclaimer's: a lock's under its `.recovery`,
105
+ * taken with its record (createRecorded), a held `.recovery` skipped; the file read again, renamed aside, the aside copy
106
+ * read again and linked back where it now holds a record (EEXIST there is the path taken since, left to its holder).
107
+ * A record that parses is kept, under its rules (a dead holder's, our own pid's, the 60 s age, which a restore resets:
108
+ * not this rule's). Answers the paths removed.
109
+ */
110
+ export declare function removeCarriedLocks(roots: readonly string[], options: {
111
+ stateDir: string;
112
+ before: number;
113
+ }): string[];
114
+ /** Name a bookkeeping phase within an existing acquisition; never acquire another lock. */
115
+ export declare function withStorageLockOperation<T>(path: string, operation: string, fn: () => T): T;
61
116
  /**
62
117
  * The default store: a thin, faithful pass-through to `node:fs`. Every method preserves
63
118
  * the exact behavior the kernel had before the seam existed — the durable append
@@ -66,6 +121,51 @@ export interface WorldStore {
66
121
  */
67
122
  export declare class FsWorldStore implements WorldStore {
68
123
  read(path: string): string | null;
124
+ /**
125
+ * A small file's text, kept while its own facts stand. THE GUARANTEE: the key is the path's own lstat (device,
126
+ * inode, size, modification and change times); this process's own writes through the store drop what is kept at
127
+ * once; another process's write is seen when any of those facts moves. That is the guarantee a tree's stamp
128
+ * already rests on for its logs (their size and modification time), with the inode and change time added: a
129
+ * replaced file (writeAtomic) is another inode, a file written in place has another time. What it cannot see is a
130
+ * rewrite to the same size on the same or a reused inode within one tick of the file system's clock, with no check
131
+ * between; the logs' stamp has the same limit. A link is read through, and not kept.
132
+ * A text read after a write that came between the lstat and the read is kept under the OLDER key, so the next
133
+ * check finds the facts moved and reads again: what is kept is never newer than its key, and never served past it.
134
+ */
135
+ private readonly kept;
136
+ readKept(path: string): string | null;
137
+ /**
138
+ * A TREE'S GENERATION: one file beside a tree's three files, a byte longer after every write of any of them, so a
139
+ * reader that has the tree's stamp asks ONE question to know it still stands (log.ts treeFacts), where it asked
140
+ * three, two of them of files a World with no parent does not have.
141
+ *
142
+ * WHAT MAKES IT SOUND. A writer appends a byte BEFORE its write and another AFTER it; a reader takes the
143
+ * generation's facts BEFORE it reads the files' own. The file only grows, so its size never repeats on one inode,
144
+ * and a replaced or removed file is another inode or none. So for any write W and any reader that kept a stamp S
145
+ * under generation G: if W's first byte is after G was read, the kept G is behind and S is not served; if it is
146
+ * before, then either W itself was before S's own reads (S holds it), or W's second byte is after G was read, and
147
+ * again G is behind. An append is one call the system orders among all writers: each byte is one append of its
148
+ * own, whole or not at all, on a POSIX filesystem and in a tab's one kernel (browser-substrate
149
+ * packages/node/src/kernel-virtual-filesystem.ts appendFileSync, an O_APPEND open and writeAll, which sends a write
150
+ * of at most DATA_BYTES as one SYS_write request the kernel serves whole; or, by a file step, its table's own
151
+ * O_APPEND open and write of the one byte, filesystem.ts appendFileBytes). The proof rests on that; log.ts
152
+ * appendToBranchLog's (`generationAfterOwnWrite`: one write is exactly two bytes) as well.
153
+ *
154
+ * WHERE THAT STOPS. (1) A writer that dies between its write and its second byte, with a reader's whole check
155
+ * between its first byte and its write: that reader keeps the older stamp until the next write of the tree. (2) A
156
+ * writer of these files that does not come through a store of this version (an older package, a copy made over a
157
+ * live directory by another program): the generation does not move. A directory made or removed whole has no
158
+ * generation or another's, which serves nothing kept. (3) A stamp that names files outside its own directory (a
159
+ * World with a parent: its view and its ancestors' logs) is never kept under a generation (log.ts).
160
+ */
161
+ generation(dirPath: string): string | null;
162
+ /** One write is `moved` twice, a byte each: the same file, those two bytes longer. */
163
+ generationAfterOwnWrite(dirPath: string, before: string): string | null;
164
+ /** One more byte on the generation beside `path`, where `path` is one of a tree's files. A directory that is not
165
+ * there has no reader to tell: the write that makes it is followed by the byte that makes its generation. */
166
+ private moved;
167
+ /** A write of `path`, with the generation beside it moved before and after where it is one of a tree's files. */
168
+ private writing;
69
169
  readLines(path: string): string[];
70
170
  readRange(path: string, start: number): string | null;
71
171
  append(path: string, data: string): void;
@@ -79,17 +179,18 @@ export declare class FsWorldStore implements WorldStore {
79
179
  remove(path: string): void;
80
180
  mkdir(dirPath: string): void;
81
181
  list(dirPath: string): string[];
182
+ /** The real path of each path already resolved: a state directory's does not move under a running process, and
183
+ * every history lock asked for it again. A path that does not exist yet is not kept. */
184
+ private readonly canonical;
82
185
  canonicalPath(path: string): string;
83
186
  stat(path: string): WorldStat | null;
84
187
  /** Run `fn` holding an exclusive cross-process file lock. The lockfile records
85
- * `{pid, hostname, at}`; a contender that finds a stale lock (dead pid or age >
188
+ * identity, operation, caller and any nested wait; a contender that finds a stale lock (dead pid or age >
86
189
  * LOCK_STALE_MS) reclaims it by atomically renaming it aside — so a crashed holder
87
190
  * can't wedge the world forever. Reclaim is race-safe: only the process that wins
88
191
  * the rename clears the stale inode, and the exclusive `wx` create still decides the
89
192
  * winner. (Moved verbatim from storage.ts `withFileLock`.) */
90
- withLock<T>(lockPath: string, fn: () => T, options?: {
91
- retainLiveOwner?: boolean;
92
- }): T;
193
+ withLock<T>(lockPath: string, fn: () => T, options?: WorldLockOptions): T;
93
194
  }
94
195
  /**
95
196
  * An in-memory store. Files are entries in a `Map<path, string>`; directories are