@routier/core 0.4.0 → 0.6.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.
Files changed (35) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +88 -438
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +0 -1
  5. package/dist/index.js +94 -443
  6. package/dist/index.js.map +1 -1
  7. package/dist/plugins/TelemetryDbPlugin.d.ts +43 -0
  8. package/dist/plugins/index.cjs +82 -1
  9. package/dist/plugins/index.cjs.map +1 -1
  10. package/dist/plugins/index.d.ts +2 -0
  11. package/dist/plugins/index.js +88 -3
  12. package/dist/plugins/index.js.map +1 -1
  13. package/dist/plugins/resultShape.d.ts +35 -0
  14. package/dist/transfer/ChunkEncoder.d.ts +60 -0
  15. package/dist/transfer/decoder.d.ts +29 -0
  16. package/dist/transfer/fillers.d.ts +36 -0
  17. package/dist/transfer/index.cjs +873 -0
  18. package/dist/transfer/index.cjs.map +1 -0
  19. package/dist/transfer/index.d.ts +47 -0
  20. package/dist/transfer/index.js +872 -0
  21. package/dist/transfer/index.js.map +1 -0
  22. package/dist/transfer/plan.d.ts +94 -0
  23. package/dist/transfer/types.d.ts +138 -0
  24. package/package.json +9 -9
  25. package/dist/capabilities/Capability.d.ts +0 -11
  26. package/dist/capabilities/PerformanceCapability.d.ts +0 -13
  27. package/dist/capabilities/TracingCapability.d.ts +0 -11
  28. package/dist/capabilities/index.cjs +0 -820
  29. package/dist/capabilities/index.cjs.map +0 -1
  30. package/dist/capabilities/index.d.ts +0 -4
  31. package/dist/capabilities/index.js +0 -808
  32. package/dist/capabilities/index.js.map +0 -1
  33. package/dist/capabilities/performance/PerformanceTracker.d.ts +0 -11
  34. package/dist/capabilities/tracing/CallTraceManager.d.ts +0 -12
  35. package/dist/capabilities/types.d.ts +0 -17
@@ -0,0 +1,35 @@
1
+ import type { PropertyInfo } from '../schema/PropertyInfo';
2
+ import type { QueryField } from './query/types';
3
+ /**
4
+ * What a statement or command RETURNS, described before it runs.
5
+ *
6
+ * A plugin's builder knows this and nothing else knows it: the shape of a result comes from the
7
+ * projection, the join aliases, or the `RETURNING` list, none of which survive into the SQL as
8
+ * anything a reader could recover. So the builder states it, once, beside the statement it built.
9
+ *
10
+ * Deliberately says nothing about what anyone does with the result. It is a description, not an
11
+ * instruction — the same description serves a driver that transfers rows across a worker
12
+ * boundary, one that hands them straight back, and one that only wants to know the column order.
13
+ * A consumer that needs more turns this into whatever it needs: `buildTransferPlan` in
14
+ * `@routier/core/transfer` is one such consumer, and it is not privileged.
15
+ */
16
+ export type ResultColumn = {
17
+ /** Exact name the engine will return, including any projection or join alias. */
18
+ readonly name: string;
19
+ /**
20
+ * The schema property behind the column, or `null`.
21
+ *
22
+ * `null` for an expression — a computed value, an aggregate, anything with no declared type
23
+ * to reason from. A consumer that wants to treat the value specially needs the property; one
24
+ * that only wants names does not.
25
+ */
26
+ readonly property: PropertyInfo<any> | null;
27
+ };
28
+ /**
29
+ * The columns a `map` projection selects.
30
+ *
31
+ * Named by `sourceName`, which is what the statement actually emits; the rename to
32
+ * `destinationName` happens in the translator, after the rows come back. A field with no
33
+ * `property` is an expression.
34
+ */
35
+ export declare const mappedResultColumns: (fields: readonly QueryField[]) => ResultColumn[];
@@ -0,0 +1,60 @@
1
+ import { EncodedTransfer, TransferPlan } from './types';
2
+ /**
3
+ * Fills one chunk at a time from row values, and emits it with the buffers its transport can hand
4
+ * over.
5
+ *
6
+ * One encoder per result, not per chunk: a column that falls back to `clone` stays there for
7
+ * every later chunk, and a forward-only cursor cannot rewind to re-encode what it already yielded.
8
+ *
9
+ * Usage is a loop — `appendRow` or `appendRecord` until `isFull`, `take`, repeat, then `take` once
10
+ * more for the short final chunk. A zero-row result takes exactly one chunk with `rowCount: 0`.
11
+ */
12
+ export declare class ChunkEncoder {
13
+ private readonly columns;
14
+ private readonly fillers;
15
+ private readonly inheritedNames;
16
+ private rows;
17
+ constructor(plan: TransferPlan);
18
+ /** Rows in the chunk being filled. */
19
+ get rowCount(): number;
20
+ get isFull(): boolean;
21
+ /** The column names, in the order a row's values must arrive in. */
22
+ get columnNames(): readonly string[];
23
+ /**
24
+ * Adds one row, its values in plan column order.
25
+ *
26
+ * A value that does not belong in its column's encoding sends that column to `clone` for the
27
+ * rest of the result, carrying the rows already written with it. Nothing is coerced into a
28
+ * typed array.
29
+ */
30
+ appendRow(values: readonly unknown[]): void;
31
+ /**
32
+ * Adds one row from a NAME-KEYED record, reading each planned column out of it.
33
+ *
34
+ * For an engine that yields records rather than positional tuples — a document store, a
35
+ * key-value store, a driver that returns row objects. Projecting to an array is the caller's
36
+ * alternative, and getting that order wrong is silent corruption rather than an error, so the
37
+ * mapping belongs here once instead of in every plugin.
38
+ *
39
+ * A column the record does not carry is `null`, not an error. Records are legitimately
40
+ * heterogeneous outside a fixed-schema table, and the plan is what decides the result shape.
41
+ */
42
+ appendRecord(record: Record<string, unknown>): void;
43
+ /**
44
+ * A plain read, unless a planned name is one the prototype chain answers for.
45
+ *
46
+ * `record['__proto__']` on an object literal returns `Object.prototype` rather than
47
+ * `undefined`, and `toString` returns a function — either would be encoded as a value. The
48
+ * own-property test that avoids it costs a call per field, so it is only taken when a name in
49
+ * this plan actually needs it.
50
+ */
51
+ private readField;
52
+ /**
53
+ * Emits the filled chunk and readies the encoder for the next one.
54
+ *
55
+ * Transfer DETACHES the emitted buffers, so the fillers allocate fresh arrays here rather
56
+ * than reusing them. Reading a chunk's typed arrays after this is a use-after-transfer.
57
+ */
58
+ take(): EncodedTransfer;
59
+ private fallBack;
60
+ }
@@ -0,0 +1,29 @@
1
+ import { EncodedChunk, TransferPlan } from './types';
2
+ /**
3
+ * A chunk's JSON document did not parse.
4
+ *
5
+ * Reported as its own shape so a caller can retry the request WITHOUT a plan and get today's
6
+ * clone path, which parses row by row and tolerates a field holding text that is not JSON.
7
+ * Every other decode failure is a real error.
8
+ *
9
+ * Read structurally rather than with `instanceof`: an error constructed in another realm — Jest
10
+ * gives each test file its own — fails the prototype test for exactly the cases this classifies.
11
+ */
12
+ export type TransferJsonError = Error & {
13
+ readonly transferJsonColumn: string;
14
+ };
15
+ export declare const isTransferJsonError: (error: unknown) => error is TransferJsonError;
16
+ /** Emptied between tests. Not part of the decoding contract. */
17
+ export declare const clearDecoderCache: () => void;
18
+ export declare const isTransferCodecSupported: () => boolean;
19
+ /**
20
+ * Decodes one chunk into final-shape row objects — real booleans, `Date` objects, parsed JSON.
21
+ *
22
+ * Not the raw storage shape. The entity needs the final shape either way, and decoding to raw and
23
+ * re-shaping afterwards measured slower (156ms against 140ms at 100,000 rows). An absent or null
24
+ * value becomes JavaScript `null`, never `undefined` and never an absent property.
25
+ *
26
+ * A column that fell back to `clone` in the worker comes back RAW, and the caller still owes it
27
+ * whatever shaping that column would otherwise have had.
28
+ */
29
+ export declare const decodeChunk: (plan: TransferPlan, chunk: EncodedChunk) => unknown[];
@@ -0,0 +1,36 @@
1
+ import { EncodedColumn, TransferEncoding } from './types';
2
+ /**
3
+ * One column being filled, one strategy per encoding.
4
+ *
5
+ * `set` answers `false` rather than coercing a value that does not belong in its encoding. A
6
+ * schema type does not prove what an engine will actually return — custom serializers,
7
+ * migrations and external writers can put anything in a field — so the encoder validates every
8
+ * value it writes instead of trusting the plan. The caller turns a refusal into a fallback to
9
+ * `clone`.
10
+ */
11
+ export interface ColumnFiller {
12
+ readonly encoding: TransferEncoding;
13
+ set(index: number, value: unknown): boolean;
14
+ /** Rows `0..count` as raw values, which is what a fallback to `clone` has to carry forward. */
15
+ drain(count: number): unknown[];
16
+ emit(rowCount: number, transferables: ArrayBufferLike[]): EncodedColumn;
17
+ /** Readies the filler for the next chunk. Transfer detaches the buffers, so they are replaced. */
18
+ reset(): void;
19
+ }
20
+ /**
21
+ * Raw values in a plain array, structured-cloned as they are.
22
+ *
23
+ * Strings live here and are never encoded. `TextEncoder` loses to clone by a wide margin —
24
+ * 14.0ms against 8.3ms for 4,000 rows of 2KB text — because cloning a V8 string is a native
25
+ * memcpy.
26
+ */
27
+ export declare class CloneFiller implements ColumnFiller {
28
+ readonly encoding: "clone";
29
+ private data;
30
+ constructor(seed?: unknown[]);
31
+ set(index: number, value: unknown): boolean;
32
+ drain(count: number): unknown[];
33
+ emit(rowCount: number): EncodedColumn;
34
+ reset(): void;
35
+ }
36
+ export declare const createFiller: (encoding: TransferEncoding) => ColumnFiller;