@routier/core 0.7.0 → 0.8.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 (47) hide show
  1. package/dist/codegen/blocks.d.ts +17 -1
  2. package/dist/codegen/handlers/types.d.ts +13 -5
  3. package/dist/codegen/index.cjs +28 -0
  4. package/dist/codegen/index.cjs.map +1 -1
  5. package/dist/codegen/index.js +28 -0
  6. package/dist/codegen/index.js.map +1 -1
  7. package/dist/collections/MemoryDataCollection.d.ts +2 -4
  8. package/dist/collections/index.cjs +127 -15
  9. package/dist/collections/index.cjs.map +1 -1
  10. package/dist/collections/index.js +127 -15
  11. package/dist/collections/index.js.map +1 -1
  12. package/dist/expressions/index.cjs +226 -4
  13. package/dist/expressions/index.cjs.map +1 -1
  14. package/dist/expressions/index.js +228 -5
  15. package/dist/expressions/index.js.map +1 -1
  16. package/dist/expressions/parser.d.ts +42 -1
  17. package/dist/index.cjs +753 -345
  18. package/dist/index.cjs.map +1 -1
  19. package/dist/index.js +756 -345
  20. package/dist/index.js.map +1 -1
  21. package/dist/plugins/EphemeralDataPlugin.d.ts +8 -0
  22. package/dist/plugins/index.cjs +566 -49
  23. package/dist/plugins/index.cjs.map +1 -1
  24. package/dist/plugins/index.js +566 -48
  25. package/dist/plugins/index.js.map +1 -1
  26. package/dist/plugins/query/QueryOptionsCollection.d.ts +15 -5
  27. package/dist/plugins/query/index.d.ts +1 -0
  28. package/dist/plugins/query/renames.d.ts +27 -0
  29. package/dist/plugins/query/types.d.ts +15 -1
  30. package/dist/plugins/translators/SqlTranslator.d.ts +15 -0
  31. package/dist/schema/SchemaDefinition.d.ts +8 -0
  32. package/dist/schema/changeTracker.d.ts +10 -0
  33. package/dist/schema/index.cjs +291 -274
  34. package/dist/schema/index.cjs.map +1 -1
  35. package/dist/schema/index.d.ts +1 -0
  36. package/dist/schema/index.js +294 -276
  37. package/dist/schema/index.js.map +1 -1
  38. package/dist/schema/types.d.ts +8 -7
  39. package/dist/schema/utils/storageDates.d.ts +25 -0
  40. package/dist/transfer/index.cjs.map +1 -1
  41. package/dist/transfer/index.js.map +1 -1
  42. package/dist/utilities/index.cjs +74 -29
  43. package/dist/utilities/index.cjs.map +1 -1
  44. package/dist/utilities/index.js +74 -29
  45. package/dist/utilities/index.js.map +1 -1
  46. package/package.json +2 -2
  47. package/dist/codegen/utils.d.ts +0 -22
@@ -38,6 +38,9 @@ export declare class QueryOptionsCollection<T> {
38
38
  * the shared collection before executing. Without restoring, a re-executed terminal —
39
39
  * the whole point of a subscribed queryable — stacks its option a second time and
40
40
  * runs it over the first execution's scalar result.
41
+ *
42
+ * The item objects are shared with the snapshot. Nothing reports on them, because every
43
+ * dispatch sends a `forDispatch` copy, so a restore brings back no reports.
41
44
  */
42
45
  snapshot(): () => void;
43
46
  /** Takes an item as it stands — same object, same index, same target and reason. */
@@ -65,14 +68,21 @@ export declare class QueryOptionsCollection<T> {
65
68
  reportEngineDivergence(item: QueryCollectionItem<any, any>): void;
66
69
  private report;
67
70
  /**
68
- * Forgets what any previous dispatch reported.
71
+ * A copy of the collection for one dispatch to a plugin, with nothing reported on it.
69
72
  *
70
73
  * Capability is answered per dispatch, so a report is only an answer for the execution that
71
- * produced it. The items are shared with any snapshot, so a report mutated in place otherwise
72
- * survives a restore and a second terminal on the same queryable replays options the plugin
73
- * did run a `skip` applied twice, over rows already windowed.
74
+ * produced it. Reports are written onto items, and the items of a queryable's collection
75
+ * outlive any one execution: a snapshot shares them, and a subscription dispatches the same
76
+ * query on every change. A report left on them replays options the plugin did run on the
77
+ * next execution, such as a `skip` applied twice over rows already windowed, or hands a
78
+ * renamed filter to memory that the engine could have run.
79
+ *
80
+ * Each item keeps its index, name, value and target. A half from `split`/`splitAt` is copied
81
+ * with a copy of its origin, and its items are that copy's items, so a report on the half still
82
+ * cascades over the whole dispatch without reaching the collection it was copied from.
74
83
  */
75
- forgetReports(): void;
84
+ forDispatch(): QueryOptionsCollection<T>;
85
+ private copyForDispatch;
76
86
  /** The options the database did not run, in the order they were written. */
77
87
  notExecuted(): QueryCollectionItem<any, any>[];
78
88
  split(): {
@@ -4,5 +4,6 @@ export * from './formatExplanation';
4
4
  export * from './join';
5
5
  export * from './Query';
6
6
  export * from './QueryOptionsCollection';
7
+ export * from './renames';
7
8
  export * from './types';
8
9
  export * from './similarity';
@@ -0,0 +1,27 @@
1
+ import { QueryOptionsCollection } from "./QueryOptionsCollection";
2
+ /**
3
+ * The options that name a property by what the caller wrote, and so can name a renamed one.
4
+ *
5
+ * `sum`, `min`, `max` and `distinct` are not among them: they carry no property, and read what the
6
+ * `map` in front of them projected. A report on that `map` ends the database phase, so they run in
7
+ * memory behind it.
8
+ */
9
+ export type PropertyReadingOption = "filter" | "sort" | "nearest" | "map" | "group";
10
+ /**
11
+ * Hands back every option over a property stored under a `.from()` name, for the datastore to run
12
+ * in memory.
13
+ *
14
+ * Core keeps such an option with the database, because only the plugin knows whether its backend
15
+ * reads storage names. One that translates the option — SQL renders the column from
16
+ * `getResolvedName()` — needs nothing from here. One that runs the caller's lambda over rows as it
17
+ * stores them reads a key the row does not have, and answers wrongly without an error: that plugin
18
+ * calls this before it reads anything, and the datastore finishes the query after deserialization,
19
+ * where the in-memory names exist.
20
+ *
21
+ * Reported as `missing-capability`: the backend cannot express the option as written, and like
22
+ * every capability, that is only knowable by the plugin.
23
+ *
24
+ * @param names Which options to check, for a plugin that resolves some of them itself — Mongo renders
25
+ * filters and sorts through the stored path, and runs `nearest`, `map` and `group` in JavaScript.
26
+ */
27
+ export declare const reportRenamedProperties: (options: QueryOptionsCollection<any>, names?: readonly PropertyReadingOption[]) => void;
@@ -14,7 +14,16 @@ export type QueryField = {
14
14
  sourceName: string;
15
15
  destinationName: string;
16
16
  isRename: boolean;
17
+ /** The property the field's value is read from, when it reads exactly one. */
17
18
  property?: PropertyInfo<unknown>;
19
+ /** Every property the field's value is read from. Absent when the selector could not be parsed. */
20
+ reads?: PropertyInfo<unknown>[];
21
+ /**
22
+ * `false` when the value is computed from `property` rather than being it, as in `x.createdDate.getTime()`,
23
+ * or when the selector could not be parsed. Absent on a field built from a property rather than a
24
+ * selector, which is that property.
25
+ */
26
+ isDirectProperty?: boolean;
18
27
  getter: <T>(data: Record<string, unknown>) => T;
19
28
  };
20
29
  export type QueryOptionExecutionTarget = "database" | "memory";
@@ -28,7 +37,7 @@ export type QueryOptionName = keyof QueryOptionValueMap<unknown>;
28
37
  * option after it. Reporting a later one would name a symptom of this one.
29
38
  */
30
39
  /** Why core planned an option for memory, decided when the option is added. */
31
- export type MemoryExecutionReason = "not-parsable" | "unmapped-property" | "renamed-property" | "map-rename" | "after-nearest" | "after-join" | "cross-plugin-join" | "predicate-error" | "after-window";
40
+ export type MemoryExecutionReason = "not-parsable" | "unmapped-property" | "map-rename" | "after-nearest" | "after-join" | "cross-plugin-join" | "predicate-error" | "after-window";
32
41
  /**
33
42
  * What became of an option planned for the database.
34
43
  *
@@ -70,11 +79,14 @@ export type QueryOption<T, K extends QueryOptionName> = {
70
79
  export type QueryOptionValueMap<T extends {}> = {
71
80
  skip: number;
72
81
  take: number;
82
+ /** `property`, `reads` and `isDirectProperty` mean what they do on a {@link QueryField}. */
73
83
  sort: {
74
84
  selector: GenericFunction<T, T[keyof T]>;
75
85
  direction: QueryOrdering;
76
86
  propertyName: string;
77
87
  property?: PropertyInfo<T> | null;
88
+ reads?: PropertyInfo<T>[];
89
+ isDirectProperty?: boolean;
78
90
  };
79
91
  map: {
80
92
  selector: GenericFunction<T, any>;
@@ -101,6 +113,8 @@ export type QueryOptionValueMap<T extends {}> = {
101
113
  selector: GenericFunction<T, T[keyof T]>;
102
114
  propertyName: string;
103
115
  property?: PropertyInfo<T> | null;
116
+ reads?: PropertyInfo<T>[];
117
+ isDirectProperty?: boolean;
104
118
  vector: number[];
105
119
  count: number;
106
120
  };
@@ -1,6 +1,7 @@
1
1
  import { QueryOption } from "../query/types";
2
2
  import { IQuery } from "../types";
3
3
  import { DataTranslator } from "./DataTranslator";
4
+ import { ITranslatedValue } from "./types";
4
5
  /**
5
6
  * What the statement that produced these rows actually did.
6
7
  *
@@ -16,6 +17,20 @@ export type SqlPushdown = {
16
17
  export declare class SqlTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {
17
18
  protected readonly pushedDown: SqlPushdown;
18
19
  constructor(query: IQuery<TRoot, TShape>, pushedDown?: SqlPushdown);
20
+ /**
21
+ * Dates back as Dates, before the caller's selectors run over the rows.
22
+ *
23
+ * A `group` key and a `map` are the caller's lambdas, run here over rows as the engine returned them.
24
+ * SQLite, D1 and libSQL hand a date back as the TEXT it was stored as, which has no `getFullYear()`
25
+ * and groups apart from the Date the entity holds. Revived at storage paths and in place, which the
26
+ * datastore's deserialization still reads, and after `decodeJsonColumns`, so a date inside a JSON
27
+ * column is revived too. Only a string is converted, so an engine that returns a Date (PostgreSQL,
28
+ * PGlite, MySQL) is left alone, and so is a row already revived.
29
+ *
30
+ * Not a joined statement's rows, which are tuples, each half already deserialized. Nor rows whose
31
+ * `group` or `map` was handed back, which the datastore runs after deserializing them.
32
+ */
33
+ translate(data: unknown): ITranslatedValue<TShape>;
19
34
  count<TResult extends number>(data: unknown, _: QueryOption<TShape, "count">): TResult;
20
35
  min<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, "min">): TResult;
21
36
  max<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, "max">): TResult;
@@ -36,6 +36,14 @@ export declare class SchemaDefinition<T extends {}> extends SchemaBase<T, any> {
36
36
  */
37
37
  get '~standard'(): StandardJSONSchemaV1.Props<InferCreateType<T>, InferType<T>>;
38
38
  private createReturnFunction;
39
+ /**
40
+ * Compiles `builder` into a function taking `fnArgs`.
41
+ *
42
+ * A builder with bindings is compiled one level out: an outer function whose parameters are
43
+ * the bindings, called once here with their values, returns the function that is kept. The
44
+ * bound values become closure variables of that function, so the per-call cost is a context
45
+ * read rather than anything resolved by name.
46
+ */
39
47
  private createFunction;
40
48
  modify<R>(builder: (d: {
41
49
  function: <UU, I = never>(fn: (entity: InferType<CompiledSchema<T>>, collectionName: CollectionName, injected: I) => UU, injected?: I) => SchemaFunction<UU, I, "unmapped">;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Builds the proxy factory that change-tracks an entity.
3
+ *
4
+ * Generated schema code receives the result as a bound value — a parameter of the generated
5
+ * factory — and never refers to this module by name. Name references do not survive a minifier,
6
+ * which renames the declaration but cannot see inside generated source text (#40, #46). The
7
+ * returned function holds no per-entity state, so one per compiled schema is shared by every
8
+ * entity it tracks.
9
+ */
10
+ export declare function createChangeTracker(): <TEntity extends {}>(entity: TEntity, path?: string, parent?: TEntity) => TEntity;