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.
- package/README.md +49 -6
- package/dist/bun-wasm-loader.d.ts +1 -0
- package/dist/bun-wasm-loader.js +20 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +93 -0
- package/{src → dist}/generated/sync_wasm_bg.wasm +0 -0
- package/dist/host.d.ts +12 -0
- package/dist/host.js +1512 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +4 -0
- package/dist/mutation-error.d.ts +9 -0
- package/dist/mutation-error.js +23 -0
- package/dist/node-wasm-loader.d.ts +1 -0
- package/dist/node-wasm-loader.js +22 -0
- package/dist/post-commit.d.ts +13 -0
- package/dist/post-commit.js +31 -0
- package/dist/query-compiler.d.ts +4 -0
- package/dist/query-compiler.js +4 -0
- package/dist/sql-storage-adapter.d.ts +69 -0
- package/dist/sql-storage-adapter.js +194 -0
- package/dist/transaction-query.d.ts +72 -0
- package/dist/transaction-query.js +379 -0
- package/dist/types.d.ts +159 -0
- package/dist/types.js +5 -0
- package/dist/vite-wasm-loader.d.ts +3 -0
- package/dist/vite-wasm-loader.js +24 -0
- package/dist/wasm.d.ts +1 -0
- package/dist/wasm.js +7 -0
- package/dist/write-safeguards.d.ts +53 -0
- package/dist/write-safeguards.js +186 -0
- package/package.json +59 -19
- package/src/bun-wasm-loader.ts +0 -16
- package/src/config.ts +0 -102
- package/src/harness-config.ts +0 -487
- package/src/harness-worker.ts +0 -33
- package/src/host.ts +0 -1958
- package/src/index.ts +0 -47
- package/src/ingest-harness-worker.ts +0 -535
- package/src/mutation-error.ts +0 -28
- package/src/platform-probe-worker.ts +0 -418
- package/src/post-commit.ts +0 -40
- package/src/query-compiler.ts +0 -16
- package/src/sql-storage-adapter.ts +0 -254
- package/src/transaction-query.ts +0 -494
- package/src/types.ts +0 -195
- package/src/wasm-platform.ts +0 -10
- package/src/wasm.ts +0 -34
- package/src/write-safeguards.ts +0 -248
- /package/{src → dist}/generated/package.json +0 -0
- /package/{src → dist}/generated/sync_wasm.d.ts +0 -0
- /package/{src → dist}/generated/sync_wasm.js +0 -0
- /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'
|
package/src/write-safeguards.ts
DELETED
|
@@ -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
|