@bjornpagen/bumbledb 1.0.0 → 1.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.
- package/COOKBOOK.md +64 -27
- package/README.md +21 -20
- package/dist/capacity.d.ts +1 -1
- package/dist/changes.d.ts +4 -5
- package/dist/changes.d.ts.map +1 -1
- package/dist/changes.js +37 -34
- package/dist/changes.js.map +1 -1
- package/dist/close.d.ts +2 -2
- package/dist/codec.d.ts +5 -6
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +6 -6
- package/dist/codec.js.map +1 -1
- package/dist/compile.d.ts +4 -6
- package/dist/compile.d.ts.map +1 -1
- package/dist/compile.js +6 -6
- package/dist/compile.js.map +1 -1
- package/dist/db-native.d.ts +43 -56
- package/dist/db-native.d.ts.map +1 -1
- package/dist/db-native.js.map +1 -1
- package/dist/db.d.ts +43 -28
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +77 -63
- package/dist/db.js.map +1 -1
- package/dist/errors.d.ts +4 -8
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +4 -8
- package/dist/errors.js.map +1 -1
- package/dist/fields.d.ts +4 -5
- package/dist/fields.d.ts.map +1 -1
- package/dist/fields.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/internal/log.d.ts +4 -4
- package/dist/internal/log.d.ts.map +1 -1
- package/dist/internal/log.js +1 -1
- package/dist/internal/log.js.map +1 -1
- package/dist/law.d.ts +1 -1
- package/dist/migration.d.ts +5 -7
- package/dist/migration.d.ts.map +1 -1
- package/dist/migration.js +8 -9
- package/dist/migration.js.map +1 -1
- package/dist/native.d.ts +2 -2
- package/dist/native.d.ts.map +1 -1
- package/dist/native.js.map +1 -1
- package/dist/query/lower.d.ts +1 -1
- package/dist/result.d.ts +10 -25
- package/dist/result.d.ts.map +1 -1
- package/dist/result.js +7 -12
- package/dist/result.js.map +1 -1
- package/dist/rows.d.ts +10 -16
- package/dist/rows.d.ts.map +1 -1
- package/dist/rows.js +8 -45
- package/dist/rows.js.map +1 -1
- package/dist/runtime-codes.d.ts +1 -1
- package/dist/runtime-codes.d.ts.map +1 -1
- package/dist/runtime-codes.js +1 -2
- package/dist/runtime-codes.js.map +1 -1
- package/dist/runtime-errors.d.ts +3 -15
- package/dist/runtime-errors.d.ts.map +1 -1
- package/dist/runtime-errors.js +1 -5
- package/dist/runtime-errors.js.map +1 -1
- package/dist/runtime-native.d.ts +18 -48
- package/dist/runtime-native.d.ts.map +1 -1
- package/dist/runtime-native.js.map +1 -1
- package/dist/runtime.d.ts +12 -29
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +16 -57
- package/dist/runtime.js.map +1 -1
- package/dist/shape.d.ts +3 -4
- package/dist/shape.d.ts.map +1 -1
- package/dist/spec.d.ts +2 -2
- package/dist/spec.js +1 -1
- package/dist/statements.js +2 -2
- package/dist/statements.js.map +1 -1
- package/pack-provenance.json +3 -3
- package/package.json +4 -4
- package/src/capacity.ts +1 -1
- package/src/changes.ts +50 -48
- package/src/close.ts +2 -2
- package/src/codec.ts +8 -24
- package/src/compile.ts +8 -10
- package/src/db-native.ts +37 -83
- package/src/db.ts +156 -135
- package/src/errors.ts +4 -8
- package/src/fields.ts +4 -5
- package/src/index.ts +6 -5
- package/src/internal/log.ts +2 -7
- package/src/law.ts +1 -1
- package/src/migration.ts +8 -16
- package/src/native.ts +2 -3
- package/src/query/lower.ts +1 -1
- package/src/result.ts +16 -45
- package/src/rows.ts +12 -65
- package/src/runtime-codes.ts +1 -2
- package/src/runtime-errors.ts +1 -5
- package/src/runtime-native.ts +15 -68
- package/src/runtime.ts +53 -122
- package/src/shape.ts +3 -4
- package/src/spec.ts +2 -2
- package/src/statements.ts +2 -2
package/src/runtime.ts
CHANGED
|
@@ -1,43 +1,21 @@
|
|
|
1
1
|
import { Context, Duration, Effect, Exit, Layer } from "effect"
|
|
2
2
|
import type { CloseReport, OutstandingWork } from "#runtime-errors.ts"
|
|
3
3
|
import { CloseFailure, DbError, dbError } from "#runtime-errors.ts"
|
|
4
|
-
import type {
|
|
5
|
-
CloseWire,
|
|
6
|
-
OperationHandle,
|
|
7
|
-
OptionsWire,
|
|
8
|
-
PolicyWire,
|
|
9
|
-
RepositoryLockHandle,
|
|
10
|
-
RuntimeHandle
|
|
11
|
-
} from "#runtime-native.ts"
|
|
4
|
+
import type { CloseWire, OperationHandle, OptionsWire, RepositoryLockHandle, RuntimeHandle } from "#runtime-native.ts"
|
|
12
5
|
import { runtimeNative } from "#runtime-native.ts"
|
|
13
6
|
|
|
14
|
-
export interface ExecutionPolicy {
|
|
15
|
-
readonly inputBytes: bigint
|
|
16
|
-
readonly workingBytes: bigint
|
|
17
|
-
readonly scratchBytes: bigint
|
|
18
|
-
readonly resultBytes: bigint
|
|
19
|
-
readonly rows: bigint
|
|
20
|
-
readonly workUnits: bigint
|
|
21
|
-
readonly timeout: Duration.Input
|
|
22
|
-
}
|
|
23
|
-
|
|
24
7
|
export interface NativeRuntimeOptions {
|
|
25
|
-
readonly workers
|
|
26
|
-
readonly queueCapacity
|
|
27
|
-
readonly cleanupCapacity
|
|
28
|
-
readonly ownerCapacity
|
|
29
|
-
readonly nativeHandleCapacity
|
|
30
|
-
readonly
|
|
31
|
-
readonly workingBytes: bigint
|
|
32
|
-
readonly scratchBytes: bigint
|
|
33
|
-
readonly resultBytes: bigint
|
|
34
|
-
readonly chunkBytes: bigint
|
|
35
|
-
readonly cleanupTimeout: Duration.Input
|
|
8
|
+
readonly workers?: number
|
|
9
|
+
readonly queueCapacity?: number
|
|
10
|
+
readonly cleanupCapacity?: number
|
|
11
|
+
readonly ownerCapacity?: number
|
|
12
|
+
readonly nativeHandleCapacity?: number
|
|
13
|
+
readonly cleanupTimeout?: Duration.Input
|
|
36
14
|
}
|
|
37
15
|
|
|
38
16
|
interface RuntimeService {
|
|
39
17
|
readonly close: () => Effect.Effect<CloseReport>
|
|
40
|
-
readonly inspect: (
|
|
18
|
+
readonly inspect: () => Effect.Effect<OutstandingWork, DbError>
|
|
41
19
|
}
|
|
42
20
|
|
|
43
21
|
const owners = new WeakMap<RuntimeService, RuntimeHandle>()
|
|
@@ -51,43 +29,23 @@ function count(value: number, operation: string): number {
|
|
|
51
29
|
return value
|
|
52
30
|
}
|
|
53
31
|
|
|
54
|
-
function bytes(value: bigint, operation: string): bigint {
|
|
55
|
-
if (typeof value !== "bigint" || value < 0n || value > 0xffffffffffffffffn) throw invalid(operation)
|
|
56
|
-
return value
|
|
57
|
-
}
|
|
58
|
-
|
|
59
32
|
function millis(value: Duration.Input, operation: string): number {
|
|
60
33
|
const duration = Duration.toMillis(value)
|
|
61
34
|
if (!Number.isFinite(duration) || duration < 0 || duration > 0xffffffff) throw invalid(operation)
|
|
62
35
|
return Math.ceil(duration)
|
|
63
36
|
}
|
|
64
37
|
|
|
65
|
-
export function policyWire(work: ExecutionPolicy, operation: string): PolicyWire {
|
|
66
|
-
return {
|
|
67
|
-
inputBytes: bytes(work.inputBytes, operation),
|
|
68
|
-
workingBytes: bytes(work.workingBytes, operation),
|
|
69
|
-
scratchBytes: bytes(work.scratchBytes, operation),
|
|
70
|
-
resultBytes: bytes(work.resultBytes, operation),
|
|
71
|
-
rows: bytes(work.rows, operation),
|
|
72
|
-
workUnits: bytes(work.workUnits, operation),
|
|
73
|
-
timeoutMs: millis(work.timeout, operation)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
38
|
function options(value: NativeRuntimeOptions): OptionsWire {
|
|
78
39
|
const operation = "NativeRuntime.acquire"
|
|
79
40
|
return {
|
|
80
|
-
workers: count(value.workers, operation),
|
|
81
|
-
queueCapacity: count(value.queueCapacity, operation),
|
|
82
|
-
cleanupCapacity: count(value.cleanupCapacity, operation),
|
|
83
|
-
ownerCapacity: count(value.ownerCapacity, operation),
|
|
84
|
-
nativeHandleCapacity:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
resultBytes: bytes(value.resultBytes, operation),
|
|
89
|
-
chunkBytes: bytes(value.chunkBytes, operation),
|
|
90
|
-
cleanupTimeoutMs: count(millis(value.cleanupTimeout, operation), operation)
|
|
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)
|
|
91
49
|
}
|
|
92
50
|
}
|
|
93
51
|
|
|
@@ -97,8 +55,7 @@ function failure(operation: string, cause: unknown): DbError {
|
|
|
97
55
|
|
|
98
56
|
function closeReport(operation: string, report: CloseWire): CloseReport {
|
|
99
57
|
// A payload-less native "failed" drain (cleanup capacity exhausted, or
|
|
100
|
-
// owner teardown failed)
|
|
101
|
-
// CloseReport policy: it decodes as the core `Internal` reason — the
|
|
58
|
+
// owner teardown failed) decodes as the core `Internal` reason — the
|
|
102
59
|
// same mapping the log bridge applies, so one wire arm has one meaning.
|
|
103
60
|
// It is deliberately NOT `QueueFull`: a failed drain is never retryable
|
|
104
61
|
// submit backpressure.
|
|
@@ -170,14 +127,6 @@ function afterClose<A, E, R>(
|
|
|
170
127
|
return effect.pipe(Effect.onExit(() => Effect.die(new CloseFailure({ operation, report }))))
|
|
171
128
|
}
|
|
172
129
|
|
|
173
|
-
/** Independent caps intersect: a delivery request cannot enlarge `work.resultBytes`. */
|
|
174
|
-
export function deliveryResultBytes(requested: bigint, work: ExecutionPolicy): bigint {
|
|
175
|
-
if (typeof requested !== "bigint" || requested < 0n) {
|
|
176
|
-
throw invalid("deliveryResultBytes")
|
|
177
|
-
}
|
|
178
|
-
return requested < work.resultBytes ? requested : work.resultBytes
|
|
179
|
-
}
|
|
180
|
-
|
|
181
130
|
function close(handle: RuntimeHandle): Effect.Effect<CloseReport> {
|
|
182
131
|
return drain("NativeRuntime.close", (callback) => runtimeNative.runtimeClose(handle, callback))
|
|
183
132
|
}
|
|
@@ -258,54 +207,41 @@ const acquire = Effect.fn("NativeRuntime.acquire")(function* (configuration: Nat
|
|
|
258
207
|
const wire = options(configuration)
|
|
259
208
|
handle = runtimeNative.runtimeOpen(wire)
|
|
260
209
|
const owner = handle
|
|
261
|
-
const lease = runtimeNative.runtimeReady(
|
|
262
|
-
|
|
263
|
-
{
|
|
264
|
-
inputBytes: 0n,
|
|
265
|
-
workingBytes: 0n,
|
|
266
|
-
scratchBytes: 0n,
|
|
267
|
-
resultBytes: 0n,
|
|
268
|
-
rows: 0n,
|
|
269
|
-
workUnits: 1n,
|
|
270
|
-
timeoutMs: wire.cleanupTimeoutMs
|
|
271
|
-
},
|
|
272
|
-
() => {
|
|
273
|
-
if (signal.aborted) {
|
|
274
|
-
try {
|
|
275
|
-
runtimeNative.runtimeClose(owner, (report) => {
|
|
276
|
-
stash.report = closeReport("NativeRuntime.acquire.cancel", report)
|
|
277
|
-
})
|
|
278
|
-
} catch (cause) {
|
|
279
|
-
stash.report = { kind: "failed", error: failure("NativeRuntime.acquire.cancel", cause) }
|
|
280
|
-
}
|
|
281
|
-
return
|
|
282
|
-
}
|
|
210
|
+
const lease = runtimeNative.runtimeReady(owner, () => {
|
|
211
|
+
if (signal.aborted) {
|
|
283
212
|
try {
|
|
284
|
-
runtimeNative.
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
inspect: Effect.fn("NativeRuntime.inspect")(function* (work) {
|
|
288
|
-
yield* nativeOperation(
|
|
289
|
-
"NativeRuntime.inspect",
|
|
290
|
-
(callback) =>
|
|
291
|
-
runtimeNative.runtimeReady(owner, policyWire(work, "NativeRuntime.inspect"), callback),
|
|
292
|
-
() => undefined
|
|
293
|
-
)
|
|
294
|
-
return runtimeNative.runtimeInspect(owner)
|
|
295
|
-
})
|
|
296
|
-
}
|
|
297
|
-
owners.set(service, owner)
|
|
298
|
-
resume(Effect.succeed(service))
|
|
213
|
+
runtimeNative.runtimeClose(owner, (report) => {
|
|
214
|
+
stash.report = closeReport("NativeRuntime.acquire.cancel", report)
|
|
215
|
+
})
|
|
299
216
|
} catch (cause) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
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
|
|
304
230
|
)
|
|
305
|
-
|
|
231
|
+
return runtimeNative.runtimeInspect(owner)
|
|
232
|
+
})
|
|
306
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
|
+
)
|
|
307
243
|
}
|
|
308
|
-
)
|
|
244
|
+
})
|
|
309
245
|
} catch (cause) {
|
|
310
246
|
const error = failure("NativeRuntime.acquire", cause)
|
|
311
247
|
resume(
|
|
@@ -334,7 +270,7 @@ const acquire = Effect.fn("NativeRuntime.acquire")(function* (configuration: Nat
|
|
|
334
270
|
export class NativeRuntime extends Context.Service<NativeRuntime, RuntimeService>()(
|
|
335
271
|
"@bjornpagen/bumbledb/NativeRuntime"
|
|
336
272
|
) {
|
|
337
|
-
static layer(options: NativeRuntimeOptions): Layer.Layer<NativeRuntime, DbError> {
|
|
273
|
+
static layer(options: NativeRuntimeOptions = {}): Layer.Layer<NativeRuntime, DbError> {
|
|
338
274
|
return Layer.effect(NativeRuntime, acquire(options))
|
|
339
275
|
}
|
|
340
276
|
}
|
|
@@ -368,24 +304,19 @@ function joinLockRelease(operation: string, owner: RepositoryLockHandle): Effect
|
|
|
368
304
|
|
|
369
305
|
/**
|
|
370
306
|
* Internal log seam: stamped mint only. Cleanup is registered before
|
|
371
|
-
* the interruptible acquire
|
|
307
|
+
* the interruptible acquire: `acquireRelease({ interruptible })`
|
|
372
308
|
* installs the finalizer only after acquire succeeds. Interrupt, defect,
|
|
373
309
|
* and acquire failure all run the same slot finalizer — empty slot is
|
|
374
310
|
* a no-op. No `runtimeDirectoryAcquire`, no core `Db`, no JS bookkeeping.
|
|
375
311
|
*/
|
|
376
312
|
export const internalAcquireRepositoryLock = Effect.fn("internalAcquireRepositoryLock")(function* (
|
|
377
313
|
operation: string,
|
|
378
|
-
directory: string
|
|
379
|
-
work: ExecutionPolicy
|
|
314
|
+
directory: string
|
|
380
315
|
) {
|
|
381
316
|
if (directory.length === 0) {
|
|
382
317
|
return yield* Effect.fail(invalid(operation))
|
|
383
318
|
}
|
|
384
319
|
const runtime = yield* runtimeHandle()
|
|
385
|
-
const wire = yield* Effect.try({
|
|
386
|
-
try: () => policyWire(work, operation),
|
|
387
|
-
catch: () => invalid(operation)
|
|
388
|
-
})
|
|
389
320
|
const closeOp = `${operation}.repositoryLock`
|
|
390
321
|
return yield* Effect.uninterruptibleMask((restore) =>
|
|
391
322
|
Effect.gen(function* () {
|
|
@@ -407,7 +338,7 @@ export const internalAcquireRepositoryLock = Effect.fn("internalAcquireRepositor
|
|
|
407
338
|
const owner = yield* restore(
|
|
408
339
|
nativeOperationWith(
|
|
409
340
|
operation,
|
|
410
|
-
(callback) => runtimeNative.logRepositoryLockAcquire(runtime,
|
|
341
|
+
(callback) => runtimeNative.logRepositoryLockAcquire(runtime, directory, callback),
|
|
411
342
|
runtimeNative.logRepositoryLockTake,
|
|
412
343
|
(value) => value
|
|
413
344
|
)
|
|
@@ -422,7 +353,7 @@ export const internalAcquireRepositoryLock = Effect.fn("internalAcquireRepositor
|
|
|
422
353
|
})
|
|
423
354
|
|
|
424
355
|
/** Internal first executor consumer; not a replacement row codec or public hash API. */
|
|
425
|
-
export const hashChunk = Effect.fn("bumbledb.hashChunk")(function* (input: Uint8Array
|
|
356
|
+
export const hashChunk = Effect.fn("bumbledb.hashChunk")(function* (input: Uint8Array) {
|
|
426
357
|
const runtime = yield* NativeRuntime
|
|
427
358
|
const handle = owners.get(runtime)
|
|
428
359
|
if (handle === undefined) return yield* Effect.fail(invalid("hashChunk"))
|
|
@@ -430,7 +361,7 @@ export const hashChunk = Effect.fn("bumbledb.hashChunk")(function* (input: Uint8
|
|
|
430
361
|
"hashChunk",
|
|
431
362
|
(callback) => {
|
|
432
363
|
if (!(input instanceof Uint8Array) || !(input.buffer instanceof ArrayBuffer)) throw invalid("hashChunk")
|
|
433
|
-
return runtimeNative.runtimeHash(handle,
|
|
364
|
+
return runtimeNative.runtimeHash(handle, input, callback)
|
|
434
365
|
},
|
|
435
366
|
(value) => {
|
|
436
367
|
if (value === null) throw dbError("hashChunk", { _tag: "Internal" })
|
package/src/shape.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Query } from "#query/lower.ts"
|
|
2
2
|
import type { ParamsRecord } from "#query/scope.ts"
|
|
3
3
|
/**
|
|
4
|
-
* Shared derived
|
|
4
|
+
* Shared derived types: `S` is a
|
|
5
5
|
* declared core schema value's type, `Rel<S>` its ordinary (writable)
|
|
6
6
|
* relations, `Fact<R>` the inferred row object, `Key<R>` the primary-key
|
|
7
7
|
* object accepted by `QueryReader.get`, and `QueryTemplate<S, P, A>` the
|
|
@@ -17,15 +17,14 @@ type Rel<S extends AnySchema> = Extract<S["relations"][keyof S["relations"]], An
|
|
|
17
17
|
/**
|
|
18
18
|
* The primary-key object of a relation: the fields of its FIRST
|
|
19
19
|
* materialized key statement (a closed relation's synthetic `(id)`,
|
|
20
|
-
* otherwise the first declared `key`).
|
|
21
|
-
* there is no fresh-implied key — so the exact projection is a schema
|
|
20
|
+
* otherwise the first declared `key`). The exact projection is a schema
|
|
22
21
|
* fact, verified at execution against the compiled tables; the type admits
|
|
23
22
|
* any subset of the fact's own fields and the runtime refuses a mismatch
|
|
24
23
|
* with a typed `DbError` before any native work.
|
|
25
24
|
*/
|
|
26
25
|
type Key<R extends AnyRelation> = Partial<Fact<R>>
|
|
27
26
|
|
|
28
|
-
/**
|
|
27
|
+
/** Immutable typed query template. */
|
|
29
28
|
type QueryTemplate<S extends AnySchema, P extends ParamsRecord, A> = Query<S["relations"], A, P>
|
|
30
29
|
|
|
31
30
|
export type { Key, QueryTemplate, Rel }
|
package/src/spec.ts
CHANGED
|
@@ -58,7 +58,7 @@ type CapacityWindowSpec =
|
|
|
58
58
|
/**
|
|
59
59
|
* One field: name, structural type, and host newtype label. There is no
|
|
60
60
|
* `fresh` mark: the database issues no identity, and key laws are declared
|
|
61
|
-
* statements
|
|
61
|
+
* statements.
|
|
62
62
|
*/
|
|
63
63
|
interface FieldSpec {
|
|
64
64
|
readonly name: string
|
|
@@ -207,7 +207,7 @@ function renderLiteral(literal: LiteralSpec): string {
|
|
|
207
207
|
|
|
208
208
|
/**
|
|
209
209
|
* The canonical binary64 bit image as sixteen lowercase hex digits — the
|
|
210
|
-
* one f64 rendering
|
|
210
|
+
* one f64 rendering: every NaN is the quiet canonical NaN and
|
|
211
211
|
* `-0` renders as `+0`, mirroring the engine's `f64:0x{bits:016x}`.
|
|
212
212
|
*/
|
|
213
213
|
function f64BitsHex(value: number): string {
|
package/src/statements.ts
CHANGED
|
@@ -275,9 +275,9 @@ function capacity(
|
|
|
275
275
|
weight = options.weight.weight
|
|
276
276
|
}
|
|
277
277
|
const window = windowValue.window
|
|
278
|
-
// The unit-floor and vacuous-window ban tables are deleted
|
|
278
|
+
// The unit-floor and vacuous-window ban tables are deleted:
|
|
279
279
|
// `{1..*}`, `{N..*}` and `{0..*}` are accepted canonical laws now.
|
|
280
|
-
// CapacityDimensionMixing
|
|
280
|
+
// CapacityDimensionMixing remains — genuinely different semantics.
|
|
281
281
|
if (weight.kind === "unit" && window.kind === "range" && window.hi.kind === "durationField") {
|
|
282
282
|
throw new AuthoringError({
|
|
283
283
|
message: `a unit (count) window against the duration() bound on ${window.hi.field} mixes dimensions (C18) — weigh the source with weigh(duration(field)), or bound by a u64 field or literal`
|