orez-sync-cf-host 0.5.19 → 0.5.21

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 (52) hide show
  1. package/README.md +49 -6
  2. package/dist/bun-wasm-loader.d.ts +1 -0
  3. package/dist/bun-wasm-loader.js +20 -0
  4. package/dist/config.d.ts +3 -0
  5. package/dist/config.js +93 -0
  6. package/{src → dist}/generated/sync_wasm_bg.wasm +0 -0
  7. package/dist/host.d.ts +12 -0
  8. package/dist/host.js +1512 -0
  9. package/dist/index.d.ts +8 -0
  10. package/dist/index.js +4 -0
  11. package/dist/mutation-error.d.ts +9 -0
  12. package/dist/mutation-error.js +23 -0
  13. package/dist/node-wasm-loader.d.ts +1 -0
  14. package/dist/node-wasm-loader.js +22 -0
  15. package/dist/post-commit.d.ts +13 -0
  16. package/dist/post-commit.js +31 -0
  17. package/dist/query-compiler.d.ts +4 -0
  18. package/dist/query-compiler.js +4 -0
  19. package/dist/sql-storage-adapter.d.ts +69 -0
  20. package/dist/sql-storage-adapter.js +194 -0
  21. package/dist/transaction-query.d.ts +72 -0
  22. package/dist/transaction-query.js +379 -0
  23. package/dist/types.d.ts +159 -0
  24. package/dist/types.js +5 -0
  25. package/dist/vite-wasm-loader.d.ts +3 -0
  26. package/dist/vite-wasm-loader.js +24 -0
  27. package/dist/wasm.d.ts +1 -0
  28. package/dist/wasm.js +7 -0
  29. package/dist/write-safeguards.d.ts +53 -0
  30. package/dist/write-safeguards.js +186 -0
  31. package/package.json +59 -19
  32. package/src/bun-wasm-loader.ts +0 -16
  33. package/src/config.ts +0 -102
  34. package/src/harness-config.ts +0 -487
  35. package/src/harness-worker.ts +0 -33
  36. package/src/host.ts +0 -1958
  37. package/src/index.ts +0 -47
  38. package/src/ingest-harness-worker.ts +0 -535
  39. package/src/mutation-error.ts +0 -28
  40. package/src/platform-probe-worker.ts +0 -418
  41. package/src/post-commit.ts +0 -40
  42. package/src/query-compiler.ts +0 -16
  43. package/src/sql-storage-adapter.ts +0 -254
  44. package/src/transaction-query.ts +0 -494
  45. package/src/types.ts +0 -195
  46. package/src/wasm-platform.ts +0 -10
  47. package/src/wasm.ts +0 -34
  48. package/src/write-safeguards.ts +0 -248
  49. /package/{src → dist}/generated/package.json +0 -0
  50. /package/{src → dist}/generated/sync_wasm.d.ts +0 -0
  51. /package/{src → dist}/generated/sync_wasm.js +0 -0
  52. /package/{src → dist}/generated/sync_wasm_bg.wasm.d.ts +0 -0
package/src/wasm.ts DELETED
@@ -1,34 +0,0 @@
1
- import { initSync } from './generated/sync_wasm.js'
2
- import wasmModule from './generated/sync_wasm_bg.wasm'
3
-
4
- if (!(wasmModule instanceof WebAssembly.Module)) {
5
- throw new TypeError(
6
- '.wasm import did not resolve to WebAssembly.Module; Bun consumers must register orez-sync-cf-host/bun-wasm-loader via bunfig preload'
7
- )
8
- }
9
-
10
- initSync({ module: wasmModule })
11
-
12
- export {
13
- engine_apply_snapshot_changes,
14
- engine_apply_snapshot_page,
15
- engine_apply_upstream,
16
- engine_assemble_push_response,
17
- engine_begin_snapshot_generation,
18
- engine_compile_query,
19
- engine_finalize,
20
- engine_finalize_snapshot_generation,
21
- engine_handle_pull,
22
- engine_handle_query_pull,
23
- engine_init_query_schema,
24
- engine_init_schema,
25
- engine_invalidate,
26
- engine_memory_bytes,
27
- engine_preflight,
28
- engine_prune,
29
- engine_push_validate,
30
- engine_read_snapshot_progress,
31
- engine_record_app_error,
32
- engine_state,
33
- engine_version,
34
- } from './generated/sync_wasm.js'
@@ -1,248 +0,0 @@
1
- export type IngestBreakerReason = 'ingestBudgetExceeded' | 'ingestCursorStalled'
2
-
3
- export type IngestBreakerOptions = {
4
- budgetRows: number
5
- windowMs: number
6
- initialBackoffMs: number
7
- maxBackoffMs: number
8
- now: () => number
9
- }
10
-
11
- export type IngestBreakerStatus = {
12
- windowRows: number
13
- billableRows: number
14
- logicalRows: number
15
- budget: number
16
- windowMs: number
17
- tripped: boolean
18
- reason: IngestBreakerReason | null
19
- retryAt: number | null
20
- retryAfterMs: number
21
- consecutiveTrips: number
22
- }
23
-
24
- type Sample = { at: number; billableRows: number; logicalRows: number }
25
-
26
- export class IngestBreakerError extends Error {
27
- readonly status = 429
28
-
29
- constructor(
30
- readonly error: IngestBreakerReason,
31
- readonly windowRows: number,
32
- readonly budget: number,
33
- readonly retryAfterMs: number
34
- ) {
35
- super(`${error}: ${windowRows}/${budget} rows; retry after ${retryAfterMs}ms`)
36
- this.name = 'IngestBreakerError'
37
- }
38
- }
39
-
40
- export class IngestCircuitBreaker {
41
- readonly #options: IngestBreakerOptions
42
- #samples: Sample[] = []
43
- #billableRows = 0
44
- #logicalRows = 0
45
- #reason: IngestBreakerReason | null = null
46
- #retryAt: number | null = null
47
- #consecutiveTrips = 0
48
-
49
- constructor(options: IngestBreakerOptions) {
50
- for (const [name, value] of Object.entries(options)) {
51
- if (name === 'now') continue
52
- if (!Number.isSafeInteger(value) || Number(value) < 1)
53
- throw new TypeError(`${name} must be a positive safe integer`)
54
- }
55
- this.#options = options
56
- }
57
-
58
- #prune(now: number): void {
59
- const cutoff = now - this.#options.windowMs
60
- let remove = 0
61
- while (remove < this.#samples.length && this.#samples[remove]!.at <= cutoff) {
62
- this.#billableRows -= this.#samples[remove]!.billableRows
63
- this.#logicalRows -= this.#samples[remove]!.logicalRows
64
- remove++
65
- }
66
- if (remove > 0) this.#samples.splice(0, remove)
67
- }
68
-
69
- status(): IngestBreakerStatus {
70
- const now = this.#options.now()
71
- this.#prune(now)
72
- const retryAfterMs = Math.max(0, (this.#retryAt ?? now) - now)
73
- return {
74
- windowRows: this.#billableRows,
75
- billableRows: this.#billableRows,
76
- logicalRows: this.#logicalRows,
77
- budget: this.#options.budgetRows,
78
- windowMs: this.#options.windowMs,
79
- tripped: this.#reason !== null && retryAfterMs > 0,
80
- reason: this.#reason,
81
- retryAt: this.#retryAt,
82
- retryAfterMs,
83
- consecutiveTrips: this.#consecutiveTrips,
84
- }
85
- }
86
-
87
- assertReady(): void {
88
- const status = this.status()
89
- if (status.tripped && status.reason) {
90
- throw new IngestBreakerError(
91
- status.reason,
92
- status.windowRows,
93
- status.budget,
94
- status.retryAfterMs
95
- )
96
- }
97
- }
98
-
99
- record(rows: number): void {
100
- this.recordLogical(rows)
101
- this.recordBillable(rows)
102
- }
103
-
104
- #sample(now: number): Sample {
105
- this.#prune(now)
106
- const last = this.#samples[this.#samples.length - 1]
107
- if (last?.at === now) return last
108
- const sample = { at: now, billableRows: 0, logicalRows: 0 }
109
- this.#samples.push(sample)
110
- return sample
111
- }
112
-
113
- recordLogical(rows: number): void {
114
- if (!Number.isSafeInteger(rows) || rows <= 0) return
115
- const sample = this.#sample(this.#options.now())
116
- sample.logicalRows += rows
117
- this.#logicalRows += rows
118
- }
119
-
120
- recordBillable(rows: number): void {
121
- this.assertReady()
122
- if (!Number.isSafeInteger(rows) || rows <= 0) return
123
- const now = this.#options.now()
124
- const sample = this.#sample(now)
125
- sample.billableRows += rows
126
- this.#billableRows += rows
127
- if (this.#billableRows > this.#options.budgetRows) this.trip('ingestBudgetExceeded')
128
- }
129
-
130
- trip(reason: IngestBreakerReason): never {
131
- const now = this.#options.now()
132
- this.#consecutiveTrips++
133
- const delay = Math.min(
134
- this.#options.maxBackoffMs,
135
- this.#options.initialBackoffMs * 2 ** (this.#consecutiveTrips - 1)
136
- )
137
- this.#reason = reason
138
- this.#retryAt = now + delay
139
- throw new IngestBreakerError(
140
- reason,
141
- this.#billableRows,
142
- this.#options.budgetRows,
143
- delay
144
- )
145
- }
146
-
147
- recovered(): void {
148
- this.#reason = null
149
- this.#retryAt = null
150
- this.#consecutiveTrips = 0
151
- }
152
-
153
- restore(reason: IngestBreakerReason, retryAt: number, consecutiveTrips: number): void {
154
- if (!Number.isFinite(retryAt) || retryAt <= 0) return
155
- this.#reason = reason
156
- this.#retryAt = retryAt
157
- this.#consecutiveTrips = Math.max(1, Math.floor(consecutiveTrips) || 1)
158
- }
159
-
160
- reopen(): void {
161
- this.#samples = []
162
- this.#billableRows = 0
163
- this.#logicalRows = 0
164
- this.recovered()
165
- }
166
- }
167
-
168
- type BillableCursor = {
169
- rowsWritten?: number
170
- next?: (...args: unknown[]) => unknown
171
- one?: (...args: unknown[]) => unknown
172
- toArray?: (...args: unknown[]) => unknown
173
- raw?: (...args: unknown[]) => unknown
174
- [Symbol.iterator]?: () => Iterator<unknown>
175
- }
176
-
177
- export function trackBillableCursorRows<Cursor extends BillableCursor>(
178
- cursor: Cursor,
179
- record: (rows: number) => void
180
- ): Cursor {
181
- if (!cursor || typeof cursor !== 'object') return cursor
182
- let accountedRows = 0
183
- const account = () => {
184
- const current = Number(cursor.rowsWritten ?? 0)
185
- if (!Number.isSafeInteger(current) || current <= accountedRows) return
186
- const delta = current - accountedRows
187
- accountedRows = current
188
- record(delta)
189
- }
190
- const wrapIterator = (iterator: Iterator<unknown>): IterableIterator<unknown> => {
191
- const next = iterator.next.bind(iterator)
192
- return {
193
- next(...args: [] | [unknown]) {
194
- try {
195
- return next(...args)
196
- } finally {
197
- account()
198
- }
199
- },
200
- [Symbol.iterator]() {
201
- return this
202
- },
203
- }
204
- }
205
- let proxy: Cursor
206
- proxy = new Proxy(cursor, {
207
- get(target, property) {
208
- const value = Reflect.get(target, property, target)
209
- if (property === Symbol.iterator) return () => proxy as unknown as Iterator<unknown>
210
- if (
211
- (property === 'next' || property === 'one' || property === 'toArray') &&
212
- typeof value === 'function'
213
- ) {
214
- return (...args: unknown[]) => {
215
- try {
216
- return Reflect.apply(value, target, args)
217
- } finally {
218
- account()
219
- }
220
- }
221
- }
222
- if (property === 'raw' && typeof value === 'function') {
223
- return (...args: unknown[]) =>
224
- wrapIterator(Reflect.apply(value, target, args) as Iterator<unknown>)
225
- }
226
- return typeof value === 'function' ? value.bind(target) : value
227
- },
228
- })
229
- account()
230
- return proxy
231
- }
232
-
233
- export function retryDelayMs(
234
- attempt: number,
235
- initialBackoffMs: number,
236
- maxBackoffMs: number
237
- ): number {
238
- return Math.min(maxBackoffMs, initialBackoffMs * 2 ** Math.max(0, attempt - 1))
239
- }
240
-
241
- export function shouldRetryDelegatedPush(
242
- responseStatus: number | null,
243
- attempt: number,
244
- maxAttempts: number
245
- ): boolean {
246
- if (attempt >= maxAttempts) return false
247
- return responseStatus === null || responseStatus === 429 || responseStatus >= 500
248
- }
File without changes
File without changes
File without changes
File without changes