@bjornpagen/bumbledb 1.3.1 → 2.0.0-rc.1
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/COOKBOOK.md +153 -77
- package/README.md +107 -41
- package/dist/alternatives.d.ts +5 -6
- package/dist/alternatives.d.ts.map +1 -1
- package/dist/alternatives.js +5 -6
- package/dist/alternatives.js.map +1 -1
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +85 -0
- package/dist/bin.js.map +1 -0
- package/dist/capacity.d.ts +14 -17
- package/dist/capacity.d.ts.map +1 -1
- package/dist/capacity.js +7 -7
- package/dist/capacity.js.map +1 -1
- package/dist/changes.d.ts +32 -40
- package/dist/changes.d.ts.map +1 -1
- package/dist/changes.js +86 -104
- package/dist/changes.js.map +1 -1
- package/dist/closed.d.ts +2 -2
- package/dist/closed.d.ts.map +1 -1
- package/dist/closed.js +5 -5
- package/dist/closed.js.map +1 -1
- package/dist/codec.d.ts +13 -27
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +20 -21
- package/dist/codec.js.map +1 -1
- package/dist/compile.d.ts +26 -50
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +75 -64
- package/dist/compile.js.map +1 -1
- package/dist/database/database.d.ts +98 -0
- package/dist/database/database.d.ts.map +1 -0
- package/dist/database/database.js +249 -0
- package/dist/database/database.js.map +1 -0
- package/dist/database/driver.d.ts +40 -0
- package/dist/database/driver.d.ts.map +1 -0
- package/dist/database/driver.js +68 -0
- package/dist/database/driver.js.map +1 -0
- package/dist/database/fs.d.ts +12 -0
- package/dist/database/fs.d.ts.map +1 -0
- package/dist/database/fs.js +120 -0
- package/dist/database/fs.js.map +1 -0
- package/dist/database/generate.d.ts +26 -0
- package/dist/database/generate.d.ts.map +1 -0
- package/dist/database/generate.js +102 -0
- package/dist/database/generate.js.map +1 -0
- package/dist/database/hosted.d.ts +32 -0
- package/dist/database/hosted.d.ts.map +1 -0
- package/dist/database/hosted.js +44 -0
- package/dist/database/hosted.js.map +1 -0
- package/dist/database/io.d.ts +94 -0
- package/dist/database/io.d.ts.map +1 -0
- package/dist/database/io.js +35 -0
- package/dist/database/io.js.map +1 -0
- package/dist/database/mem.d.ts +26 -0
- package/dist/database/mem.d.ts.map +1 -0
- package/dist/database/mem.js +67 -0
- package/dist/database/mem.js.map +1 -0
- package/dist/database/migration.d.ts +55 -0
- package/dist/database/migration.d.ts.map +1 -0
- package/dist/database/migration.js +46 -0
- package/dist/database/migration.js.map +1 -0
- package/dist/database/s3.d.ts +36 -0
- package/dist/database/s3.d.ts.map +1 -0
- package/dist/database/s3.js +141 -0
- package/dist/database/s3.js.map +1 -0
- package/dist/db.d.ts +44 -128
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +163 -287
- package/dist/db.js.map +1 -1
- package/dist/engine.d.ts +7 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +2 -0
- package/dist/engine.js.map +1 -0
- package/dist/errors.d.ts +152 -46
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +107 -19
- package/dist/errors.js.map +1 -1
- package/dist/face.d.ts +5 -5
- package/dist/face.d.ts.map +1 -1
- package/dist/face.js +6 -6
- package/dist/face.js.map +1 -1
- package/dist/fields.d.ts +4 -5
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js +3 -3
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +60 -57
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -28
- package/dist/index.js.map +1 -1
- package/dist/judgment.d.ts +1 -1
- package/dist/judgment.js +1 -1
- package/dist/law.d.ts +16 -68
- package/dist/law.d.ts.map +1 -1
- package/dist/law.js +3 -3
- package/dist/law.js.map +1 -1
- package/dist/lower.d.ts +3 -3
- package/dist/lower.d.ts.map +1 -1
- package/dist/lower.js +35 -39
- package/dist/lower.js.map +1 -1
- package/dist/native/addon.d.ts +23 -0
- package/dist/native/addon.d.ts.map +1 -0
- package/dist/native/addon.js +15 -0
- package/dist/native/addon.js.map +1 -0
- package/dist/native/binding.d.ts +996 -0
- package/dist/native/json.d.ts +14 -0
- package/dist/native/json.d.ts.map +1 -0
- package/dist/native/json.js +73 -0
- package/dist/native/json.js.map +1 -0
- package/dist/native/load.d.ts +9 -0
- package/dist/native/load.d.ts.map +1 -0
- package/dist/native/load.js +30 -0
- package/dist/native/load.js.map +1 -0
- package/dist/native/op.d.ts +29 -0
- package/dist/native/op.d.ts.map +1 -0
- package/dist/native/op.js +50 -0
- package/dist/native/op.js.map +1 -0
- package/dist/query/atom.d.ts +13 -14
- package/dist/query/atom.d.ts.map +1 -1
- package/dist/query/atom.js +2 -2
- package/dist/query/atom.js.map +1 -1
- package/dist/query/compute.d.ts +4 -4
- package/dist/query/compute.d.ts.map +1 -1
- package/dist/query/compute.js +4 -4
- package/dist/query/compute.js.map +1 -1
- package/dist/query/find.d.ts +8 -8
- package/dist/query/find.d.ts.map +1 -1
- package/dist/query/find.js +1 -1
- package/dist/query/lower.d.ts +22 -17
- package/dist/query/lower.d.ts.map +1 -1
- package/dist/query/lower.js +230 -343
- package/dist/query/lower.js.map +1 -1
- package/dist/query/run.d.ts +5 -5
- package/dist/query/run.d.ts.map +1 -1
- package/dist/query/run.js +32 -15
- package/dist/query/run.js.map +1 -1
- package/dist/query/scope.d.ts +20 -28
- package/dist/query/scope.d.ts.map +1 -1
- package/dist/query/scope.js +7 -7
- package/dist/query/scope.js.map +1 -1
- package/dist/query/segments.d.ts +2 -2
- package/dist/query/segments.d.ts.map +1 -1
- package/dist/query/segments.js +3 -3
- package/dist/query/segments.js.map +1 -1
- package/dist/relation.d.ts +1 -1
- package/dist/relation.d.ts.map +1 -1
- package/dist/relation.js +4 -4
- package/dist/relation.js.map +1 -1
- package/dist/result.d.ts +15 -22
- package/dist/result.d.ts.map +1 -1
- package/dist/result.js +30 -39
- package/dist/result.js.map +1 -1
- package/dist/rows.d.ts +9 -33
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +8 -12
- package/dist/rows.js.map +1 -1
- package/dist/runtime.d.ts +17 -20
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +41 -205
- package/dist/runtime.js.map +1 -1
- package/dist/scalar.d.ts +4 -4
- package/dist/scalar.d.ts.map +1 -1
- package/dist/scalar.js +24 -8
- package/dist/scalar.js.map +1 -1
- package/dist/schema.d.ts +7 -18
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +18 -228
- package/dist/schema.js.map +1 -1
- package/dist/selection.d.ts +4 -4
- package/dist/selection.d.ts.map +1 -1
- package/dist/selection.js +5 -5
- package/dist/selection.js.map +1 -1
- package/dist/shape.d.ts +5 -5
- package/dist/shape.d.ts.map +1 -1
- package/dist/spec.d.ts +7 -79
- package/dist/spec.d.ts.map +1 -1
- package/dist/spec.js.map +1 -1
- package/dist/statements.d.ts +3 -3
- package/dist/statements.d.ts.map +1 -1
- package/dist/statements.js +10 -10
- package/dist/statements.js.map +1 -1
- package/dist/uuid.d.ts +1 -1
- package/dist/uuid.d.ts.map +1 -1
- package/dist/uuid.js +1 -1
- package/dist/uuid.js.map +1 -1
- package/dist/values.d.ts +2 -2
- package/dist/values.d.ts.map +1 -1
- package/dist/values.js +2 -2
- package/dist/values.js.map +1 -1
- package/package.json +18 -18
- package/src/alternatives.ts +7 -8
- package/src/bin.ts +82 -0
- package/src/capacity.ts +20 -23
- package/src/changes.ts +134 -191
- package/src/closed.ts +5 -5
- package/src/codec.ts +35 -49
- package/src/compile.ts +91 -113
- package/src/database/database.ts +413 -0
- package/src/database/driver.ts +134 -0
- package/src/database/fs.ts +119 -0
- package/src/database/generate.ts +116 -0
- package/src/database/hosted.ts +102 -0
- package/src/database/io.ts +134 -0
- package/src/database/mem.ts +113 -0
- package/src/database/migration.ts +107 -0
- package/src/database/s3.ts +231 -0
- package/src/db.ts +290 -547
- package/src/engine.ts +14 -0
- package/src/errors.ts +118 -39
- package/src/face.ts +9 -9
- package/src/fields.ts +6 -7
- package/src/index.ts +92 -105
- package/src/judgment.ts +1 -1
- package/src/law.ts +18 -70
- package/src/lower.ts +61 -72
- package/src/native/addon.ts +54 -0
- package/src/native/binding.d.ts +996 -0
- package/src/native/json.ts +100 -0
- package/src/native/load.ts +31 -0
- package/src/native/op.ts +73 -0
- package/src/query/atom.ts +15 -16
- package/src/query/compute.ts +7 -7
- package/src/query/find.ts +8 -8
- package/src/query/lower.ts +270 -392
- package/src/query/run.ts +42 -21
- package/src/query/scope.ts +29 -37
- package/src/query/segments.ts +4 -4
- package/src/relation.ts +4 -4
- package/src/result.ts +53 -80
- package/src/rows.ts +18 -46
- package/src/runtime.ts +50 -277
- package/src/scalar.ts +32 -12
- package/src/schema.ts +23 -284
- package/src/selection.ts +6 -6
- package/src/shape.ts +5 -5
- package/src/spec.ts +7 -85
- package/src/statements.ts +11 -11
- package/src/uuid.ts +1 -1
- package/src/values.ts +4 -4
- package/dist/close.d.ts +0 -24
- package/dist/close.d.ts.map +0 -1
- package/dist/close.js +0 -34
- package/dist/close.js.map +0 -1
- package/dist/db-native.d.ts +0 -189
- package/dist/db-native.d.ts.map +0 -1
- package/dist/db-native.js +0 -13
- package/dist/db-native.js.map +0 -1
- package/dist/internal/log.d.ts +0 -26
- package/dist/internal/log.d.ts.map +0 -1
- package/dist/internal/log.js +0 -12
- package/dist/internal/log.js.map +0 -1
- package/dist/native.d.ts +0 -562
- package/dist/native.d.ts.map +0 -1
- package/dist/native.js +0 -123
- package/dist/native.js.map +0 -1
- package/dist/query/description.d.ts +0 -41
- package/dist/query/description.d.ts.map +0 -1
- package/dist/query/description.js +0 -311
- package/dist/query/description.js.map +0 -1
- package/dist/query/parse-ir.d.ts +0 -10
- package/dist/query/parse-ir.d.ts.map +0 -1
- package/dist/query/parse-ir.js +0 -280
- package/dist/query/parse-ir.js.map +0 -1
- package/dist/runtime-codes.d.ts +0 -2
- package/dist/runtime-codes.d.ts.map +0 -1
- package/dist/runtime-codes.js +0 -19
- package/dist/runtime-codes.js.map +0 -1
- package/dist/runtime-errors.d.ts +0 -138
- package/dist/runtime-errors.d.ts.map +0 -1
- package/dist/runtime-errors.js +0 -111
- package/dist/runtime-errors.js.map +0 -1
- package/dist/runtime-native.d.ts +0 -136
- package/dist/runtime-native.d.ts.map +0 -1
- package/dist/runtime-native.js +0 -5
- package/dist/runtime-native.js.map +0 -1
- package/dist/schema-file.d.ts +0 -7
- package/dist/schema-file.d.ts.map +0 -1
- package/dist/schema-file.js +0 -24
- package/dist/schema-file.js.map +0 -1
- package/pack-provenance.json +0 -7
- package/src/close.ts +0 -53
- package/src/db-native.ts +0 -235
- package/src/internal/log.ts +0 -46
- package/src/native.ts +0 -736
- package/src/query/description.ts +0 -424
- package/src/query/parse-ir.ts +0 -293
- package/src/runtime-codes.ts +0 -18
- package/src/runtime-errors.ts +0 -122
- package/src/runtime-native.ts +0 -181
- package/src/schema-file.ts +0 -38
package/src/runtime.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { Context, Duration, Effect,
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
4
|
-
import type {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
import { Context, Duration, Effect, Layer } from "effect"
|
|
2
|
+
import type { OutstandingWork } from "./errors.ts"
|
|
3
|
+
import { DbError, dbError } from "./errors.ts"
|
|
4
|
+
import type { RuntimeRef } from "./native/addon.ts"
|
|
5
|
+
import { addon } from "./native/addon.ts"
|
|
6
|
+
import type { RuntimeOptionsIn } from "./native/binding.d.ts"
|
|
7
|
+
import { call, scoped } from "./native/op.ts"
|
|
8
|
+
|
|
9
|
+
/** Sizing for the native runtime. The addon validates every count and picks the defaults. */
|
|
10
|
+
export interface BumbleOptions {
|
|
8
11
|
readonly workers?: number
|
|
9
12
|
readonly queueCapacity?: number
|
|
10
13
|
readonly cleanupCapacity?: number
|
|
@@ -13,290 +16,60 @@ export interface NativeRuntimeOptions {
|
|
|
13
16
|
readonly cleanupTimeout?: Duration.Input
|
|
14
17
|
}
|
|
15
18
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const owners = new WeakMap<RuntimeService, RuntimeHandle>()
|
|
22
|
-
|
|
23
|
-
function invalid(operation: string): DbError {
|
|
24
|
-
return new DbError({ operation, reason: { _tag: "InvalidArgument" } })
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function count(value: number, operation: string): number {
|
|
28
|
-
if (!Number.isSafeInteger(value) || value <= 0 || value > 0xffffffff) throw invalid(operation)
|
|
29
|
-
return value
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function millis(value: Duration.Input, operation: string): number {
|
|
33
|
-
const duration = Duration.toMillis(value)
|
|
34
|
-
if (!Number.isFinite(duration) || duration < 0 || duration > 0xffffffff) throw invalid(operation)
|
|
35
|
-
return Math.ceil(duration)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function options(value: NativeRuntimeOptions): OptionsWire {
|
|
39
|
-
const operation = "NativeRuntime.acquire"
|
|
40
|
-
return {
|
|
41
|
-
workers: value.workers === undefined ? undefined : count(value.workers, operation),
|
|
42
|
-
queueCapacity: value.queueCapacity === undefined ? undefined : count(value.queueCapacity, operation),
|
|
43
|
-
cleanupCapacity: value.cleanupCapacity === undefined ? undefined : count(value.cleanupCapacity, operation),
|
|
44
|
-
ownerCapacity: value.ownerCapacity === undefined ? undefined : count(value.ownerCapacity, operation),
|
|
45
|
-
nativeHandleCapacity:
|
|
46
|
-
value.nativeHandleCapacity === undefined ? undefined : count(value.nativeHandleCapacity, operation),
|
|
47
|
-
cleanupTimeoutMs:
|
|
48
|
-
value.cleanupTimeout === undefined ? undefined : count(millis(value.cleanupTimeout, operation), operation)
|
|
19
|
+
function wire(options: BumbleOptions): string {
|
|
20
|
+
const timeout = options.cleanupTimeout === undefined ? undefined : Duration.toMillis(options.cleanupTimeout)
|
|
21
|
+
if (timeout !== undefined && !Number.isFinite(timeout)) {
|
|
22
|
+
throw new DbError({ operation: "Bumble.layer", reason: { _tag: "InvalidArgument" } })
|
|
49
23
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
// A payload-less native "failed" drain (cleanup capacity exhausted, or
|
|
58
|
-
// owner teardown failed) decodes as the core `Internal` reason — the
|
|
59
|
-
// same mapping the log bridge applies, so one wire arm has one meaning.
|
|
60
|
-
// It is deliberately NOT `QueueFull`: a failed drain is never retryable
|
|
61
|
-
// submit backpressure.
|
|
62
|
-
return report.kind === "failed" ? { kind: "failed", error: dbError(operation, { _tag: "Internal" }) } : report
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function drain(operation: string, start: (callback: (report: CloseWire) => void) => void): Effect.Effect<CloseReport> {
|
|
66
|
-
return Effect.callback<CloseReport>((resume) => {
|
|
67
|
-
try {
|
|
68
|
-
start((report) => resume(Effect.succeed(closeReport(operation, report))))
|
|
69
|
-
} catch (cause) {
|
|
70
|
-
resume(Effect.succeed({ kind: "failed", error: failure(operation, cause) }))
|
|
71
|
-
}
|
|
72
|
-
}).pipe(Effect.uninterruptible)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
export function finalizeClose(operation: string, report: CloseReport): Effect.Effect<void> {
|
|
76
|
-
return report.kind === "closed" ? Effect.void : Effect.die(new CloseFailure({ operation, report }))
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Effect.callback's returned finalizer is interruption cleanup only
|
|
81
|
-
* (`asyncFinalizer` runs solely on interrupt Cause). If that finalizer
|
|
82
|
-
* dies, the original interrupt is dropped. Join the native drain here and
|
|
83
|
-
* always succeed so the interrupt Cause is kept; attach CloseFailure via
|
|
84
|
-
* `onExit` so both appear in the final Cause.
|
|
85
|
-
*/
|
|
86
|
-
function joinInterruptDrain(
|
|
87
|
-
operation: string,
|
|
88
|
-
start: (callback: (report: CloseWire) => void) => void,
|
|
89
|
-
stash: { report?: CloseReport }
|
|
90
|
-
): Effect.Effect<void> {
|
|
91
|
-
return drain(operation, start).pipe(
|
|
92
|
-
Effect.tap((report) => {
|
|
93
|
-
stash.report = report
|
|
94
|
-
return Effect.void
|
|
95
|
-
}),
|
|
96
|
-
Effect.asVoid
|
|
97
|
-
)
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function attachInterruptClose(
|
|
101
|
-
operation: string,
|
|
102
|
-
stash: { report?: CloseReport }
|
|
103
|
-
): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A, E, R> {
|
|
104
|
-
return (effect) =>
|
|
105
|
-
effect.pipe(
|
|
106
|
-
Effect.onExit((exit) => {
|
|
107
|
-
if (!Exit.hasInterrupts(exit)) {
|
|
108
|
-
return Effect.void
|
|
109
|
-
}
|
|
110
|
-
const report = stash.report
|
|
111
|
-
if (report === undefined || report.kind === "closed") {
|
|
112
|
-
return Effect.void
|
|
113
|
-
}
|
|
114
|
-
return Effect.die(new CloseFailure({ operation, report }))
|
|
115
|
-
})
|
|
116
|
-
)
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
function afterClose<A, E, R>(
|
|
120
|
-
operation: string,
|
|
121
|
-
report: CloseReport,
|
|
122
|
-
effect: Effect.Effect<A, E, R>
|
|
123
|
-
): Effect.Effect<A, E, R> {
|
|
124
|
-
if (report.kind === "closed") {
|
|
125
|
-
return effect
|
|
24
|
+
const input: RuntimeOptionsIn = {
|
|
25
|
+
...(options.workers === undefined ? {} : { workers: options.workers }),
|
|
26
|
+
...(options.queueCapacity === undefined ? {} : { queueCapacity: options.queueCapacity }),
|
|
27
|
+
...(options.cleanupCapacity === undefined ? {} : { cleanupCapacity: options.cleanupCapacity }),
|
|
28
|
+
...(options.ownerCapacity === undefined ? {} : { ownerCapacity: options.ownerCapacity }),
|
|
29
|
+
...(options.nativeHandleCapacity === undefined ? {} : { nativeHandleCapacity: options.nativeHandleCapacity }),
|
|
30
|
+
...(timeout === undefined ? {} : { cleanupTimeoutMs: Math.ceil(timeout) })
|
|
126
31
|
}
|
|
127
|
-
return
|
|
32
|
+
return JSON.stringify(input)
|
|
128
33
|
}
|
|
129
34
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
35
|
+
/** The live native runtime: one worker pool and handle registry per process. */
|
|
36
|
+
export class Runtime {
|
|
37
|
+
readonly #handle: RuntimeRef
|
|
38
|
+
/** The runtime's outstanding native work, after every operation queued before it settles. */
|
|
39
|
+
readonly inspect: () => Effect.Effect<OutstandingWork, DbError>
|
|
133
40
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
function startCancelDrain(operation: string, lease: OperationHandle, stash: { report?: CloseReport }): void {
|
|
140
|
-
try {
|
|
141
|
-
runtimeNative.runtimeCancel(lease, (report) => {
|
|
142
|
-
stash.report = closeReport(operation, report)
|
|
41
|
+
constructor(handle: RuntimeRef) {
|
|
42
|
+
this.#handle = handle
|
|
43
|
+
this.inspect = Effect.fn("Bumble.inspect")(function* () {
|
|
44
|
+
yield* call("Bumble.inspect", (done) => addon.runtimeReady(handle, done), addon.runtimeTake)
|
|
45
|
+
return addon.runtimeInspect(handle) as OutstandingWork
|
|
143
46
|
})
|
|
144
|
-
} catch (cause) {
|
|
145
|
-
stash.report = { kind: "failed", error: failure(operation, cause) }
|
|
146
47
|
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/** Registration returns the native lease before any completion can run in JS.
|
|
150
|
-
* Interruption cancels and joins that lease, including a late successful result.
|
|
151
|
-
* No Promise or libuv job is created for ordinary native work.
|
|
152
|
-
*/
|
|
153
|
-
export function nativeOperation<A>(
|
|
154
|
-
operation: string,
|
|
155
|
-
start: (callback: () => void) => OperationHandle,
|
|
156
|
-
accept: (value: Uint8Array | null) => A
|
|
157
|
-
): Effect.Effect<A, DbError> {
|
|
158
|
-
return nativeOperationWith(operation, start, runtimeNative.runtimeTake, accept)
|
|
159
|
-
}
|
|
160
48
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
take: (operation: OperationHandle) => Value,
|
|
165
|
-
accept: (value: Value) => A
|
|
166
|
-
): Effect.Effect<A, DbError> {
|
|
167
|
-
const stash: { report?: CloseReport } = {}
|
|
168
|
-
const cancelOp = `${operation}.cancel`
|
|
169
|
-
return attachInterruptClose(
|
|
170
|
-
cancelOp,
|
|
171
|
-
stash
|
|
172
|
-
)(
|
|
173
|
-
Effect.callback((resume, signal) => {
|
|
174
|
-
let lease: OperationHandle
|
|
175
|
-
try {
|
|
176
|
-
lease = start(() => {
|
|
177
|
-
if (signal.aborted) {
|
|
178
|
-
startCancelDrain(cancelOp, lease, stash)
|
|
179
|
-
return
|
|
180
|
-
}
|
|
181
|
-
try {
|
|
182
|
-
resume(Effect.succeed(accept(take(lease))))
|
|
183
|
-
} catch (cause) {
|
|
184
|
-
resume(Effect.fail(failure(operation, cause)))
|
|
185
|
-
}
|
|
186
|
-
})
|
|
187
|
-
} catch (cause) {
|
|
188
|
-
resume(Effect.fail(failure(operation, cause)))
|
|
189
|
-
return
|
|
190
|
-
}
|
|
191
|
-
return joinInterruptDrain(cancelOp, (callback) => runtimeNative.runtimeCancel(lease, callback), stash)
|
|
192
|
-
})
|
|
193
|
-
)
|
|
49
|
+
static handle(runtime: Runtime): RuntimeRef {
|
|
50
|
+
return runtime.#handle
|
|
51
|
+
}
|
|
194
52
|
}
|
|
195
53
|
|
|
196
|
-
const acquire = Effect.fn("
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
stash
|
|
203
|
-
)(
|
|
204
|
-
Effect.callback<RuntimeService, DbError>((resume, signal) => {
|
|
205
|
-
let handle: RuntimeHandle | undefined
|
|
206
|
-
try {
|
|
207
|
-
const wire = options(configuration)
|
|
208
|
-
handle = runtimeNative.runtimeOpen(wire)
|
|
209
|
-
const owner = handle
|
|
210
|
-
const lease = runtimeNative.runtimeReady(owner, () => {
|
|
211
|
-
if (signal.aborted) {
|
|
212
|
-
try {
|
|
213
|
-
runtimeNative.runtimeClose(owner, (report) => {
|
|
214
|
-
stash.report = closeReport("NativeRuntime.acquire.cancel", report)
|
|
215
|
-
})
|
|
216
|
-
} catch (cause) {
|
|
217
|
-
stash.report = { kind: "failed", error: failure("NativeRuntime.acquire.cancel", cause) }
|
|
218
|
-
}
|
|
219
|
-
return
|
|
220
|
-
}
|
|
221
|
-
try {
|
|
222
|
-
runtimeNative.runtimeTake(lease)
|
|
223
|
-
const service: RuntimeService = {
|
|
224
|
-
close: () => close(owner),
|
|
225
|
-
inspect: Effect.fn("NativeRuntime.inspect")(function* () {
|
|
226
|
-
yield* nativeOperation(
|
|
227
|
-
"NativeRuntime.inspect",
|
|
228
|
-
(callback) => runtimeNative.runtimeReady(owner, callback),
|
|
229
|
-
() => undefined
|
|
230
|
-
)
|
|
231
|
-
return runtimeNative.runtimeInspect(owner)
|
|
232
|
-
})
|
|
233
|
-
}
|
|
234
|
-
owners.set(service, owner)
|
|
235
|
-
resume(Effect.succeed(service))
|
|
236
|
-
} catch (cause) {
|
|
237
|
-
const error = failure("NativeRuntime.acquire", cause)
|
|
238
|
-
resume(
|
|
239
|
-
close(owner).pipe(
|
|
240
|
-
Effect.flatMap((report) => afterClose("NativeRuntime.acquire", report, Effect.fail(error)))
|
|
241
|
-
)
|
|
242
|
-
)
|
|
243
|
-
}
|
|
244
|
-
})
|
|
245
|
-
} catch (cause) {
|
|
246
|
-
const error = failure("NativeRuntime.acquire", cause)
|
|
247
|
-
resume(
|
|
248
|
-
handle === undefined
|
|
249
|
-
? Effect.fail(error)
|
|
250
|
-
: close(handle).pipe(
|
|
251
|
-
Effect.flatMap((report) => afterClose("NativeRuntime.acquire", report, Effect.fail(error)))
|
|
252
|
-
)
|
|
253
|
-
)
|
|
254
|
-
}
|
|
255
|
-
return handle === undefined
|
|
256
|
-
? Effect.void
|
|
257
|
-
: joinInterruptDrain(
|
|
258
|
-
"NativeRuntime.acquire.cancel",
|
|
259
|
-
(callback) => runtimeNative.runtimeClose(handle, callback),
|
|
260
|
-
stash
|
|
261
|
-
)
|
|
262
|
-
})
|
|
263
|
-
)
|
|
264
|
-
}),
|
|
265
|
-
(service) => service.close().pipe(Effect.flatMap((report) => finalizeClose("NativeRuntime.release", report))),
|
|
266
|
-
{ interruptible: true }
|
|
54
|
+
const acquire = Effect.fn("Bumble.layer")(function* (options: BumbleOptions) {
|
|
55
|
+
const input = yield* Effect.try({ try: () => wire(options), catch: (cause) => dbError("Bumble.layer", cause) })
|
|
56
|
+
const handle = yield* scoped(
|
|
57
|
+
"Bumble.release",
|
|
58
|
+
Effect.try({ try: () => addon.runtimeOpen(input), catch: (cause) => dbError("Bumble.layer", cause) }),
|
|
59
|
+
(owner) => (done) => addon.runtimeClose(owner, done)
|
|
267
60
|
)
|
|
61
|
+
yield* call("Bumble.layer", (done) => addon.runtimeReady(handle, done), addon.runtimeTake)
|
|
62
|
+
return new Runtime(handle)
|
|
268
63
|
})
|
|
269
64
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
) {
|
|
273
|
-
|
|
274
|
-
return Layer.effect(NativeRuntime, acquire(options))
|
|
65
|
+
/** The native runtime as an Effect service. Provide `Bumble.layer()` once in the application graph. */
|
|
66
|
+
export class Bumble extends Context.Service<Bumble, Runtime>()("@bjornpagen/bumbledb/Bumble") {
|
|
67
|
+
static layer(options: BumbleOptions = {}): Layer.Layer<Bumble, DbError> {
|
|
68
|
+
return Layer.effect(Bumble, acquire(options))
|
|
275
69
|
}
|
|
276
70
|
}
|
|
277
71
|
|
|
278
|
-
/**
|
|
279
|
-
export const runtimeHandle = Effect.
|
|
280
|
-
|
|
281
|
-
const handle = owners.get(runtime)
|
|
282
|
-
if (handle === undefined) return yield* Effect.fail(invalid("NativeRuntime.handle"))
|
|
283
|
-
return handle
|
|
284
|
-
})
|
|
285
|
-
|
|
286
|
-
/** Internal first executor consumer; not a replacement row codec or public hash API. */
|
|
287
|
-
export const hashChunk = Effect.fn("bumbledb.hashChunk")(function* (input: Uint8Array) {
|
|
288
|
-
const runtime = yield* NativeRuntime
|
|
289
|
-
const handle = owners.get(runtime)
|
|
290
|
-
if (handle === undefined) return yield* Effect.fail(invalid("hashChunk"))
|
|
291
|
-
return yield* nativeOperation(
|
|
292
|
-
"hashChunk",
|
|
293
|
-
(callback) => {
|
|
294
|
-
if (!(input instanceof Uint8Array) || !(input.buffer instanceof ArrayBuffer)) throw invalid("hashChunk")
|
|
295
|
-
return runtimeNative.runtimeHash(handle, input, callback)
|
|
296
|
-
},
|
|
297
|
-
(value) => {
|
|
298
|
-
if (value === null) throw dbError("hashChunk", { _tag: "Internal" })
|
|
299
|
-
return value
|
|
300
|
-
}
|
|
301
|
-
)
|
|
72
|
+
/** The provided runtime's native handle. */
|
|
73
|
+
export const runtimeHandle: Effect.Effect<RuntimeRef, never, Bumble> = Effect.gen(function* () {
|
|
74
|
+
return Runtime.handle(yield* Bumble)
|
|
302
75
|
})
|
package/src/scalar.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/** Query scalar nodes, with cached kind and depth. Construction is constant
|
|
2
2
|
* work; native preparation binds variables and evaluates the expressions. */
|
|
3
|
-
import { AuthoringError } from "
|
|
4
|
-
import type {
|
|
5
|
-
import
|
|
3
|
+
import { AuthoringError } from "./errors.ts"
|
|
4
|
+
import type { ScalarExprIn } from "./native/binding.d.ts"
|
|
5
|
+
import { valueIn } from "./native/json.ts"
|
|
6
|
+
import type { ValueSpec } from "./spec.ts"
|
|
6
7
|
|
|
7
8
|
/** The engine's scalar result vocabulary — distinct at the type level. */
|
|
8
9
|
type ScalarKind = "u64" | "i64" | "f64" | "bool"
|
|
@@ -82,7 +83,7 @@ const U64_MAX = (1n << 64n) - 1n
|
|
|
82
83
|
const I64_MIN = -(1n << 63n)
|
|
83
84
|
const I64_MAX = (1n << 63n) - 1n
|
|
84
85
|
|
|
85
|
-
/** Constructor admissions only
|
|
86
|
+
/** Constructor admissions only, not descendant visits. */
|
|
86
87
|
let authoringWork = 0
|
|
87
88
|
|
|
88
89
|
function scalarAuthoringWork(): number {
|
|
@@ -346,27 +347,46 @@ function queryVarsOf(node: ScalarNode): readonly ScalarQueryVar[] {
|
|
|
346
347
|
}
|
|
347
348
|
|
|
348
349
|
/** Lower each query variable through its existing binding. */
|
|
349
|
-
|
|
350
|
-
|
|
350
|
+
const ROUNDING = {
|
|
351
|
+
towardZero: "TowardZero",
|
|
352
|
+
nearestTiesAwayFromZero: "NearestTiesAwayFromZero",
|
|
353
|
+
nearestTiesToEven: "NearestTiesToEven"
|
|
354
|
+
} as const
|
|
355
|
+
|
|
356
|
+
const CAST = { toF64: "ToF64", toF64Exact: "ToF64Exact", toI64Exact: "ToI64Exact", toU64Exact: "ToU64Exact" } as const
|
|
357
|
+
|
|
358
|
+
const UNARY = { measure: "Measure", negate: "Negate", isNaN: "IsNaN", isFinite: "IsFinite" } as const
|
|
359
|
+
|
|
360
|
+
const BINARY = { add: "Add", subtract: "Subtract", multiply: "Multiply", divide: "Divide" } as const
|
|
361
|
+
|
|
362
|
+
/** Lowers a scalar expression to the addon's `ScalarExprIn`; `leaf` numbers the rule variables. */
|
|
363
|
+
function scalarWire(node: ScalarNode, leaf: (node: QueryVarLeaf) => number): ScalarExprIn {
|
|
364
|
+
const walk = (expr: ScalarNode): ScalarExprIn => scalarWire(expr, leaf)
|
|
351
365
|
switch (node.kind) {
|
|
352
366
|
case "var":
|
|
353
|
-
return { kind: "
|
|
367
|
+
return { kind: "Var", var: leaf(node) }
|
|
354
368
|
case "literal":
|
|
355
|
-
return { kind: "
|
|
369
|
+
return { kind: "Literal", value: valueIn(literalWireOf(node.value)) }
|
|
356
370
|
case "measure":
|
|
357
371
|
case "negate":
|
|
358
372
|
case "isNaN":
|
|
359
373
|
case "isFinite":
|
|
360
|
-
return { kind: node.kind, expr: walk(node.expr) }
|
|
374
|
+
return { kind: UNARY[node.kind], expr: walk(node.expr) }
|
|
361
375
|
case "cast":
|
|
362
|
-
return { kind:
|
|
376
|
+
return { kind: "Cast", cast: CAST[node.cast], expr: walk(node.expr) }
|
|
363
377
|
case "mulDiv":
|
|
364
|
-
return {
|
|
378
|
+
return {
|
|
379
|
+
kind: "MulDiv",
|
|
380
|
+
a: walk(node.a),
|
|
381
|
+
b: walk(node.b),
|
|
382
|
+
divisor: walk(node.divisor),
|
|
383
|
+
rounding: ROUNDING[node.rounding]
|
|
384
|
+
}
|
|
365
385
|
case "add":
|
|
366
386
|
case "subtract":
|
|
367
387
|
case "multiply":
|
|
368
388
|
case "divide":
|
|
369
|
-
return { kind: node.kind, left: walk(node.left), right: walk(node.right) }
|
|
389
|
+
return { kind: BINARY[node.kind], left: walk(node.left), right: walk(node.right) }
|
|
370
390
|
}
|
|
371
391
|
}
|
|
372
392
|
|