@routier/core 0.0.1-alpha.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.
Files changed (168) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/package.json +91 -0
  3. package/rspack.config.mjs +65 -0
  4. package/src/assertions/index.ts +37 -0
  5. package/src/codegen/SlotPath.ts +20 -0
  6. package/src/codegen/blocks.ts +578 -0
  7. package/src/codegen/handlers/CloneHandlerBuilder.ts +13 -0
  8. package/src/codegen/handlers/CompareHandlerBuilder.ts +13 -0
  9. package/src/codegen/handlers/DeserializeHandlerBuilder.ts +20 -0
  10. package/src/codegen/handlers/EnableChangeTrackingHandlerBuilder.ts +13 -0
  11. package/src/codegen/handlers/EnrichmentHandlerBuilder.ts +28 -0
  12. package/src/codegen/handlers/FreezeHandlerBuilder.ts +13 -0
  13. package/src/codegen/handlers/HashHandlerBuilder.ts +25 -0
  14. package/src/codegen/handlers/HashTypeHandlerBuilder.ts +11 -0
  15. package/src/codegen/handlers/IdSelectorHandlerBuilder.ts +10 -0
  16. package/src/codegen/handlers/MergeHandlerBuilder.ts +19 -0
  17. package/src/codegen/handlers/PrepareHandlerBuilder.ts +23 -0
  18. package/src/codegen/handlers/SerializeHandlerBuilder.ts +15 -0
  19. package/src/codegen/handlers/StripHandlerBuilder.ts +18 -0
  20. package/src/codegen/handlers/clone/CloneObjectHandler.ts +29 -0
  21. package/src/codegen/handlers/clone/CloneValueHandler.ts +33 -0
  22. package/src/codegen/handlers/compare/CompareObjectHandler.ts +15 -0
  23. package/src/codegen/handlers/compare/CompareValueHandler.ts +27 -0
  24. package/src/codegen/handlers/deserialize/DeserializeComputedValueHandler.ts +16 -0
  25. package/src/codegen/handlers/deserialize/DeserializeDateHandler.ts +45 -0
  26. package/src/codegen/handlers/deserialize/DeserializeFunctionHandler.ts +16 -0
  27. package/src/codegen/handlers/deserialize/DeserializeObjectHandler.ts +29 -0
  28. package/src/codegen/handlers/deserialize/DeserializeValueHandler.ts +33 -0
  29. package/src/codegen/handlers/enableChangeTracking/EnableChangeTrackingObjectHandler.ts +20 -0
  30. package/src/codegen/handlers/enableChangeTracking/EnableChangeTrackingPrimitiveValueHandler.ts +15 -0
  31. package/src/codegen/handlers/enrichment/EnrichmentComputedValueHandler.ts +37 -0
  32. package/src/codegen/handlers/enrichment/EnrichmentDefaultFunctionHandler.ts +50 -0
  33. package/src/codegen/handlers/enrichment/EnrichmentDefaultValueHandler.ts +18 -0
  34. package/src/codegen/handlers/enrichment/EnrichmentFunctionHandler.ts +38 -0
  35. package/src/codegen/handlers/enrichment/EnrichmentNullableObjectHandler.ts +44 -0
  36. package/src/codegen/handlers/enrichment/EnrichmentObjectHandler.ts +29 -0
  37. package/src/codegen/handlers/enrichment/EnrichmentObjectIdentityHandler.ts +16 -0
  38. package/src/codegen/handlers/enrichment/EnrichmentPrimitiveHandler.ts +13 -0
  39. package/src/codegen/handlers/enrichment/EnrichmentPrimitiveIdentityHandler.ts +21 -0
  40. package/src/codegen/handlers/freeze/FreezeObjectHandler.ts +20 -0
  41. package/src/codegen/handlers/freeze/FreezePrimitiveValueHandler.ts +15 -0
  42. package/src/codegen/handlers/hash/HashComputedValueHandler.ts +15 -0
  43. package/src/codegen/handlers/hash/HashDateHandler.ts +26 -0
  44. package/src/codegen/handlers/hash/HashFunctionHandler.ts +16 -0
  45. package/src/codegen/handlers/hash/HashIdentityHandler.ts +15 -0
  46. package/src/codegen/handlers/hash/HashKeyHandler.ts +26 -0
  47. package/src/codegen/handlers/hash/HashValueHandler.ts +26 -0
  48. package/src/codegen/handlers/hashType/HashTypeValueHandler.ts +20 -0
  49. package/src/codegen/handlers/idSelector/IdSelectorValueHandler.ts +28 -0
  50. package/src/codegen/handlers/index.ts +13 -0
  51. package/src/codegen/handlers/merge/MergeComputedValueHandler.ts +37 -0
  52. package/src/codegen/handlers/merge/MergeDefaultFunctionHandler.ts +40 -0
  53. package/src/codegen/handlers/merge/MergeDefaultValueHandler.ts +32 -0
  54. package/src/codegen/handlers/merge/MergeFunctionHandler.ts +16 -0
  55. package/src/codegen/handlers/merge/MergePrimitiveHandler.ts +21 -0
  56. package/src/codegen/handlers/prepare/PrepareComputedValueHandler.ts +16 -0
  57. package/src/codegen/handlers/prepare/PrepareFunctionHandler.ts +16 -0
  58. package/src/codegen/handlers/prepare/PrepareIdentityHandler.ts +21 -0
  59. package/src/codegen/handlers/prepare/PrepareKeyHandler.ts +21 -0
  60. package/src/codegen/handlers/prepare/PrepareObjectHandler.ts +38 -0
  61. package/src/codegen/handlers/prepare/PrepareValueHandler.ts +36 -0
  62. package/src/codegen/handlers/serialize/SerializeDateHandler.ts +45 -0
  63. package/src/codegen/handlers/serialize/SerializeObjectHandler.ts +28 -0
  64. package/src/codegen/handlers/serialize/SerializeValueHandler.ts +33 -0
  65. package/src/codegen/handlers/strip/StripIdentityHandler.ts +15 -0
  66. package/src/codegen/handlers/strip/StripKeyHandler.ts +15 -0
  67. package/src/codegen/handlers/strip/StripObjectHandler.ts +35 -0
  68. package/src/codegen/handlers/strip/StripValueHandler.ts +36 -0
  69. package/src/codegen/handlers/types.ts +119 -0
  70. package/src/codegen/index.ts +2 -0
  71. package/src/codegen/types.ts +2 -0
  72. package/src/codegen/utils.ts +74 -0
  73. package/src/collections/Changes.test.ts +337 -0
  74. package/src/collections/Changes.ts +177 -0
  75. package/src/collections/IdSet.ts +28 -0
  76. package/src/collections/MemoryDataCollection.test.ts +424 -0
  77. package/src/collections/MemoryDataCollection.ts +134 -0
  78. package/src/collections/SchemaCollection.ts +22 -0
  79. package/src/collections/TagCollection.test.ts +443 -0
  80. package/src/collections/TagCollection.ts +62 -0
  81. package/src/collections/index.ts +5 -0
  82. package/src/errors/SchemaError.ts +6 -0
  83. package/src/errors/index.ts +1 -0
  84. package/src/expressions/index.ts +3 -0
  85. package/src/expressions/parser.test.ts +913 -0
  86. package/src/expressions/parser.ts +661 -0
  87. package/src/expressions/types.ts +184 -0
  88. package/src/expressions/utils.test.ts +346 -0
  89. package/src/expressions/utils.ts +59 -0
  90. package/src/index.ts +12 -0
  91. package/src/performance/index.ts +26 -0
  92. package/src/pipeline/SyncronousQueue.test.ts +269 -0
  93. package/src/pipeline/SyncronousQueue.ts +30 -0
  94. package/src/pipeline/TrampolinePipeline.test.ts +374 -0
  95. package/src/pipeline/TrampolinePipeline.ts +437 -0
  96. package/src/pipeline/index.ts +2 -0
  97. package/src/plugins/EphemeralDataPlugin.ts +132 -0
  98. package/src/plugins/capabilities/DbPluginCapability.ts +111 -0
  99. package/src/plugins/capabilities/index.ts +2 -0
  100. package/src/plugins/capabilities/logging/DbPluginLoggingCapability.ts +261 -0
  101. package/src/plugins/capabilities/logging/index.ts +1 -0
  102. package/src/plugins/index.ts +6 -0
  103. package/src/plugins/query/Query.ts +67 -0
  104. package/src/plugins/query/QueryOptionsCollection.test.ts +86 -0
  105. package/src/plugins/query/QueryOptionsCollection.ts +154 -0
  106. package/src/plugins/query/index.ts +3 -0
  107. package/src/plugins/query/types.ts +46 -0
  108. package/src/plugins/replication/OptimisticReplicationDbPlugin.ts +202 -0
  109. package/src/plugins/replication/ReplicationDbPlugin.ts +137 -0
  110. package/src/plugins/replication/index.ts +3 -0
  111. package/src/plugins/replication/types.ts +5 -0
  112. package/src/plugins/translators/DataTranslator.ts +46 -0
  113. package/src/plugins/translators/JsonTranslator.test.ts +618 -0
  114. package/src/plugins/translators/JsonTranslator.ts +211 -0
  115. package/src/plugins/translators/SqlTranslator.ts +45 -0
  116. package/src/plugins/translators/index.ts +3 -0
  117. package/src/plugins/types.ts +114 -0
  118. package/src/results/Result.ts +91 -0
  119. package/src/results/index.ts +3 -0
  120. package/src/results/types.ts +17 -0
  121. package/src/results/utils.ts +15 -0
  122. package/src/schema/PropertyInfo.test.ts +479 -0
  123. package/src/schema/PropertyInfo.ts +374 -0
  124. package/src/schema/SchemaDefinition.ts +626 -0
  125. package/src/schema/builder.ts +18 -0
  126. package/src/schema/index.ts +7 -0
  127. package/src/schema/property/base/SchemaBase.ts +49 -0
  128. package/src/schema/property/base/index.ts +1 -0
  129. package/src/schema/property/modifiers/SchemaDefault.ts +29 -0
  130. package/src/schema/property/modifiers/SchemaDeserialize.ts +23 -0
  131. package/src/schema/property/modifiers/SchemaDistinct.ts +14 -0
  132. package/src/schema/property/modifiers/SchemaFrom.ts +54 -0
  133. package/src/schema/property/modifiers/SchemaIdentity.ts +13 -0
  134. package/src/schema/property/modifiers/SchemaIndex.ts +60 -0
  135. package/src/schema/property/modifiers/SchemaKey.ts +28 -0
  136. package/src/schema/property/modifiers/SchemaNullable.ts +18 -0
  137. package/src/schema/property/modifiers/SchemaOptional.ts +19 -0
  138. package/src/schema/property/modifiers/SchemaReadonly.ts +34 -0
  139. package/src/schema/property/modifiers/SchemaSerialize.ts +18 -0
  140. package/src/schema/property/modifiers/SchemaTracked.ts +14 -0
  141. package/src/schema/property/modifiers/index.ts +12 -0
  142. package/src/schema/property/types/SchemaArray.ts +50 -0
  143. package/src/schema/property/types/SchemaBoolean.ts +59 -0
  144. package/src/schema/property/types/SchemaDate.ts +58 -0
  145. package/src/schema/property/types/SchemaNumber.ts +69 -0
  146. package/src/schema/property/types/SchemaObject.ts +44 -0
  147. package/src/schema/property/types/SchemaString.ts +69 -0
  148. package/src/schema/property/types/index.ts +6 -0
  149. package/src/schema/table/SchemaComputed.ts +20 -0
  150. package/src/schema/table/SchemaFunction.ts +15 -0
  151. package/src/schema/table/index.ts +2 -0
  152. package/src/schema/types.ts +238 -0
  153. package/src/types/index.ts +5 -0
  154. package/src/utilities/arrays.test.ts +312 -0
  155. package/src/utilities/arrays.ts +12 -0
  156. package/src/utilities/dates.test.ts +388 -0
  157. package/src/utilities/dates.ts +11 -0
  158. package/src/utilities/dbPluginEventUtils.ts +44 -0
  159. package/src/utilities/index.ts +10 -0
  160. package/src/utilities/objects.ts +7 -0
  161. package/src/utilities/queryOptionsCollection.ts +16 -0
  162. package/src/utilities/replication.ts +23 -0
  163. package/src/utilities/runtime.ts +3 -0
  164. package/src/utilities/strings.ts +18 -0
  165. package/src/utilities/types.ts +1 -0
  166. package/src/utilities/uuid.ts +56 -0
  167. package/tsconfig.json +28 -0
  168. package/vitest.config.ts +11 -0
@@ -0,0 +1,211 @@
1
+ import { DataTranslator } from "./DataTranslator";
2
+ import { QueryOption } from "../query/types";
3
+ import { assertIsArray } from "../../assertions";
4
+ import { ParamsFilter } from "../../expressions";
5
+ import { isDate } from "../../utilities";
6
+
7
+ export class JsonTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {
8
+
9
+ override filter<TResult>(data: unknown, option: QueryOption<TShape, "filter">): TResult {
10
+
11
+ assertIsArray(data);
12
+
13
+ if (option.value.filter) {
14
+
15
+ if (option.value.params == null) {
16
+ // standard filtering
17
+ return data.filter(option.value.filter) as TResult;
18
+ }
19
+
20
+ // params filtering
21
+ const selector = option.value.filter as ParamsFilter<unknown, {}>
22
+ return data.filter(w => selector([w, option.value.params])) as TResult;
23
+ }
24
+
25
+ return data as TResult;
26
+ }
27
+
28
+ override map<T>(data: unknown, option: QueryOption<T, "map">): T {
29
+
30
+ if (Array.isArray(data) == false) {
31
+ throw new Error("Can only map an array of data");
32
+ }
33
+
34
+ const response = [];
35
+
36
+ // We want deserialization to flow through mappings
37
+ // TODO: Speed this up!
38
+ // Generate a function on the fly?
39
+ for (let i = 0, length = data.length; i < length; i++) {
40
+
41
+ for (let j = 0, l = option.value.fields.length; j < l; j++) {
42
+ const field = option.value.fields[j];
43
+
44
+ if (field.property != null) {
45
+ const value = field.property.getValue(data[i]);
46
+
47
+ if (value != null) {
48
+ field.property.setValue(data[i], field.property.deserialize(value));
49
+ }
50
+ }
51
+ }
52
+
53
+ response.push(option.value.selector(data[i]));
54
+ }
55
+
56
+ return response as T;
57
+ }
58
+
59
+ override count<TResult extends number>(data: unknown, _: QueryOption<TShape, "count">): TResult {
60
+
61
+ if (Array.isArray(data)) {
62
+ return data.length as TResult;
63
+ }
64
+
65
+ throw new Error("Cannot count resulting data, it must be an array. Please return array of data for function: count()");
66
+ }
67
+
68
+ override min<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, "min">): TResult {
69
+ return this._minMax(data, "min", (a: any, b: any) => a - b);
70
+ }
71
+
72
+ override max<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, "max">): TResult {
73
+ return this._minMax(data, "max", (a: any, b: any) => b - a);
74
+ }
75
+
76
+ override sort<TResult>(data: unknown, option: QueryOption<TShape, "sort">): TResult {
77
+
78
+ if (Array.isArray(data)) {
79
+
80
+ data.sort((a, b) => {
81
+ if (option.value.direction === "asc") {
82
+ return (option.value.selector(a) as any) - (option.value.selector(b) as any);
83
+ }
84
+
85
+ return (option.value.selector(b) as any) - (option.value.selector(a) as any);
86
+ });
87
+ }
88
+
89
+ return data as TResult;
90
+ }
91
+
92
+ override sum<TResult extends number>(data: unknown, _: QueryOption<TShape, "sum">): TResult {
93
+
94
+ assertIsArray(data, this._formatDataNotArrayError("sum"));
95
+
96
+ const map = this.query.options.getLast("map");
97
+
98
+ let sum = 0;
99
+ const field = this._getSelectionField("sum", map);
100
+
101
+ for (let i = 0, length = data.length; i < length; i++) {
102
+ const value = data[i];
103
+
104
+ if (typeof value !== "number") {
105
+ throw new Error(`Cannot sum, property is not a number. Property: ${field.sourceName}`);
106
+ }
107
+
108
+ sum += value;
109
+ }
110
+
111
+ return sum as TResult;
112
+ }
113
+
114
+ override distinct<TResult>(data: unknown, _: QueryOption<TShape, "distinct">): TResult {
115
+
116
+ assertIsArray(data, this._formatDataNotArrayError("distinct"));
117
+
118
+ const result = new Set<string | number | Date>();
119
+
120
+ // would be nice to have property info here for type detection
121
+ let needsDateConversion = false;
122
+
123
+ for (let i = 0, length = data.length; i < length; i++) {
124
+ const value = data[i];
125
+
126
+ if (typeof value === "number" || typeof value === "string") {
127
+ result.add(value);
128
+ continue;
129
+ }
130
+
131
+ if (isDate(value)) {
132
+ needsDateConversion = true;
133
+ result.add(value.toISOString());
134
+ continue;
135
+ }
136
+
137
+ }
138
+
139
+ if (needsDateConversion) {
140
+ return [...result].map(w => new Date(w)) as TResult;
141
+ }
142
+
143
+ return [...result] as TResult
144
+ }
145
+
146
+ override skip<TResult>(data: unknown, option: QueryOption<TShape, "skip">): TResult {
147
+
148
+ if (Array.isArray(data)) {
149
+
150
+ if (option.value > 0) {
151
+
152
+ if (data.length < option.value) {
153
+ // We don't have enough data to skip, return an empty array
154
+ return [] as TResult;
155
+ }
156
+
157
+ return data.slice(option.value) as TResult;
158
+ }
159
+
160
+ return data as TResult;
161
+ }
162
+
163
+ return data as TResult;
164
+ }
165
+
166
+ override take<TResult>(data: unknown, option: QueryOption<TShape, "take">): TResult {
167
+ if (Array.isArray(data)) {
168
+
169
+ if (option.value > 0) {
170
+
171
+ if (data.length < option.value) {
172
+ return data as TResult;
173
+ }
174
+
175
+ return data.slice(0, option.value) as TResult;
176
+ }
177
+
178
+ return data as TResult;
179
+ }
180
+
181
+ return data as TResult;
182
+ }
183
+
184
+ private _getSelectionField(name: string, mapOption: QueryOption<TShape, "map"> | null) {
185
+
186
+ if (mapOption == null ||
187
+ mapOption.value.fields.length === 0 ||
188
+ mapOption.value.fields.length > 1) {
189
+ throw new Error(`${name}() operation can only be performed when one field is mapped for a result. Ex. myset.map(x => x.someNumberOrDateOrString).${name}()`)
190
+ }
191
+
192
+ return mapOption.value.fields[0];
193
+ }
194
+
195
+ private _minMax<T extends string | number | Date>(data: unknown, name: string, sort: (a: any, b: any) => any): T {
196
+
197
+ assertIsArray(data, this._formatDataNotArrayError(name));
198
+
199
+ data.sort(sort);
200
+
201
+ if (data.length === 0) {
202
+ throw new Error("Cannot perform operation on empty array, result query contains no data")
203
+ }
204
+
205
+ return data[0] as T;
206
+ }
207
+
208
+ private _formatDataNotArrayError(functionName: string) {
209
+ return `Cannot sum resulting data, it must be an array. Please return array of data for function: ${functionName}()`
210
+ }
211
+ }
@@ -0,0 +1,45 @@
1
+ import { QueryOption } from "../query/types";
2
+ import { DataTranslator } from "./DataTranslator";
3
+
4
+ export class SqlTranslator<TRoot extends {}, TShape> extends DataTranslator<TRoot, TShape> {
5
+
6
+ count<TResult extends number>(data: unknown, _: QueryOption<TShape, "count">): TResult {
7
+ return data as TResult;
8
+ }
9
+
10
+ min<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, "min">): TResult {
11
+ return data as TResult;
12
+ }
13
+
14
+ max<TResult extends string | number | Date>(data: unknown, _: QueryOption<TShape, "max">): TResult {
15
+ return data as TResult;
16
+ }
17
+
18
+ sum<TResult extends number>(data: unknown, _: QueryOption<TShape, "sum">): TResult {
19
+ return data as TResult;
20
+ }
21
+
22
+ distinct<TResult>(data: unknown, _: QueryOption<TShape, "distinct">): TResult {
23
+ return data as TResult;
24
+ }
25
+
26
+ filter<TResult>(data: unknown, _: QueryOption<TShape, "filter">): TResult {
27
+ return data as TResult;
28
+ }
29
+
30
+ skip(data: unknown, _: QueryOption<TShape, "skip">): TShape {
31
+ return data as TShape;
32
+ }
33
+
34
+ take(data: unknown, _: QueryOption<TShape, "take">): TShape {
35
+ return data as TShape;
36
+ }
37
+
38
+ sort(data: unknown, _: QueryOption<TShape, "sort">): TShape {
39
+ return data as TShape;
40
+ }
41
+
42
+ map(data: unknown, _: QueryOption<TShape, "map">): TShape {
43
+ return data as TShape;
44
+ }
45
+ }
@@ -0,0 +1,3 @@
1
+ export * from './DataTranslator';
2
+ export * from './JsonTranslator';
3
+ export * from './SqlTranslator';
@@ -0,0 +1,114 @@
1
+ import { PluginEventCallbackPartialResult, PluginEventCallbackResult } from "../results";
2
+ import { QueryOptionsCollection } from "./query/QueryOptionsCollection";
3
+ import { CompiledSchema, InferType } from '../schema';
4
+ import { BulkPersistChanges, BulkPersistResult, SchemaCollection } from "../collections";
5
+
6
+ /**
7
+ * Interface for a database plugin, which provides query, destroy, and bulk operations.
8
+ */
9
+ export interface IDbPlugin {
10
+ /**
11
+ * Executes a query operation on the database.
12
+ * @param event The query event containing schema, parent, and query operation.
13
+ * @param done Callback with the result or error.
14
+ */
15
+ query<TRoot extends {}, TShape extends any = TRoot>(event: DbPluginQueryEvent<TRoot, TShape>, done: PluginEventCallbackResult<TShape>): void;
16
+ /**
17
+ * Destroys or cleans up the plugin, closing connections or freeing resources.
18
+ * @param done Callback with an optional error.
19
+ */
20
+ destroy(event: DbPluginEvent, done: PluginEventCallbackResult<never>): void;
21
+ /**
22
+ * Executes bulk operations (add, update, remove) on the database.
23
+ * @param event The bulk operations event containing schema, parent, and changes.
24
+ * @param done Callback with the result or error.
25
+ */
26
+ bulkPersist(event: DbPluginBulkPersistEvent, done: PluginEventCallbackPartialResult<BulkPersistResult>): void;
27
+ }
28
+
29
+ /**
30
+ * Event for a query operation, including schema, parent, and the query operation.
31
+ */
32
+ export type DbPluginQueryEvent<TRoot extends {}, TShape> = DbPluginOperationEvent<IQuery<TRoot, TShape>>;
33
+
34
+ /**
35
+ * Event for bulk operations, including schema, parent, and the entity changes.
36
+ */
37
+ export type DbPluginBulkPersistEvent = DbPluginOperationEvent<BulkPersistChanges>;
38
+
39
+ /**
40
+ * Base event for all plugin operations, containing the schema and parent.
41
+ */
42
+ export type DbPluginEvent = {
43
+ /** The compiled schema for the entity. */
44
+ schemas: SchemaCollection;
45
+
46
+ /** Unique id of the event. */
47
+ id: string;
48
+ }
49
+
50
+ /**
51
+ * Event for a specific plugin operation, extending the base event with an operation payload.
52
+ */
53
+ export type DbPluginOperationEvent<TOperation> = DbPluginEvent & {
54
+ /** The operation payload (query, changes, etc.). */
55
+ operation: TOperation;
56
+ }
57
+
58
+ /**
59
+ * Represents a collection of database plugins with a primary source and optional replicas.
60
+ * Used for implementing read/write separation and high availability.
61
+ */
62
+ export type ReplicationPluginOptions = {
63
+ /** The primary database plugin that handles all write operations, do not include in the list of replicas. */
64
+ source: IDbPlugin;
65
+ /** Array of replica database plugins that can be used for read operations. */
66
+ replicas: IDbPlugin[];
67
+ /**
68
+ * The primary database plugin that handles all read operations, do not include in the list of replicas.
69
+ * Used when the source plugin should generate the identity properties, but the read replica will only
70
+ * read data. Typically this is a MemoryPlugin. Should not be included in the list of replicas.
71
+ */
72
+ read?: IDbPlugin;
73
+ }
74
+
75
+ export type OptimisticReplicationPluginOptions = {
76
+ /** The primary database plugin that handles all write operations, do not include in the list of replicas. */
77
+ source: IDbPlugin;
78
+
79
+ /** Array of replica database plugins that can be used for read operations. */
80
+ replicas: IDbPlugin[];
81
+
82
+ /** Must be a MemoryPlugin */
83
+ read: IDbPlugin;
84
+ }
85
+
86
+
87
+ export type EntityUpdateInfo<T extends {}> = {
88
+ entity: InferType<T>,
89
+ changeType: EntityChangeType;
90
+ delta: { [key: string]: string | number | Date }
91
+ }
92
+
93
+ export type TaggedEntity<T> = {
94
+ entity: T;
95
+ tag?: unknown
96
+ }
97
+
98
+ /**
99
+ * Interface for a query operation, including expression, options, filters, and change tracking.
100
+ */
101
+ export type IQuery<TRoot extends {}, TShape> = {
102
+
103
+ /** Query options (sort, skip, take, etc.). */
104
+ options: QueryOptionsCollection<TShape>;
105
+
106
+ schema: CompiledSchema<TRoot>;
107
+ /**
108
+ * Whether change tracking is enabled for the query result.
109
+ * Only enabled when the response is not reduced/aggregated/mapped.
110
+ */
111
+ get changeTracking(): boolean;
112
+ };
113
+
114
+ export type EntityChangeType = "propertiesChanged" | "markedDirty" | "notModified";
@@ -0,0 +1,91 @@
1
+ import { PartialResultType, PluginEventPartialResultType, PluginEventResultType, ResultType } from "./types";
2
+
3
+ abstract class BaseResult {
4
+ static ERROR = "error" as const;
5
+ static SUCCESS = "success" as const;
6
+ static PARTIAL = "partial" as const;
7
+
8
+ static resolve<T>(result: ResultType<T> | PartialResultType<T>, resolve: (data: T) => void, reject: (error?: any) => void) {
9
+ if (result.ok === BaseResult.SUCCESS) {
10
+ resolve(result.data);
11
+ return;
12
+ }
13
+
14
+ if (result.ok === BaseResult.PARTIAL) {
15
+ reject({
16
+ partial: result.data,
17
+ error: result.error
18
+ });
19
+ return;
20
+ }
21
+
22
+ reject(result.error);
23
+ }
24
+
25
+ static assertSuccess<T>(result: any): asserts result is { ok: "success"; data: T } {
26
+ if (result.ok !== BaseResult.SUCCESS) {
27
+ throw new Error(`Expected success result, but got ${result.ok}: ${result.error}`);
28
+ }
29
+ }
30
+ }
31
+
32
+ export class Result extends BaseResult {
33
+ static success<T>(data: T): ResultType<T>;
34
+ static success<T>(): ResultType<never>;
35
+ static success<T>(data?: T): ResultType<T> {
36
+ return {
37
+ ok: Result.SUCCESS,
38
+ data
39
+ }
40
+ }
41
+
42
+ static error<T>(error: any): ResultType<T> {
43
+ return {
44
+ ok: Result.ERROR,
45
+ error
46
+ }
47
+ }
48
+
49
+ static partial<T>(data: T, error: any): PartialResultType<T> {
50
+ return {
51
+ ok: Result.PARTIAL,
52
+ data,
53
+ error
54
+ }
55
+ }
56
+ }
57
+
58
+ export class PluginEventResult extends BaseResult {
59
+ static success<T>(id: string, data: T): PluginEventResultType<T>;
60
+ static success<T>(id: string): PluginEventResultType<never>;
61
+ static success<T>(id: string, data?: T): PluginEventResultType<T> {
62
+ return {
63
+ id,
64
+ ok: Result.SUCCESS,
65
+ data
66
+ }
67
+ }
68
+
69
+ static error<T>(id: string, error: any): PluginEventResultType<T> {
70
+ return {
71
+ id,
72
+ ok: Result.ERROR,
73
+ error
74
+ }
75
+ }
76
+
77
+ static partial<T>(id: string, data: T, error: any): PluginEventPartialResultType<T> {
78
+ return {
79
+ id,
80
+ ok: Result.PARTIAL,
81
+ data,
82
+ error
83
+ }
84
+ }
85
+
86
+ static assertSuccess<T>(result: PluginEventResultType<T>): asserts result is { ok: "success"; data: T; id: string } {
87
+ if (result.ok !== Result.SUCCESS) {
88
+ throw new Error(`Expected success result, but got ${result.ok}: ${result.error}`);
89
+ }
90
+ }
91
+ }
@@ -0,0 +1,3 @@
1
+ export * from './Result';
2
+ export * from './types';
3
+ export * from './utils';
@@ -0,0 +1,17 @@
1
+ export type ErrorType<Extra extends {} = {}> = { error: any, ok: "error" } & Extra;
2
+ export type SuccessType<T, Extra extends {} = {}> = { data: T, ok: "success" } & Extra;
3
+ export type PartialType<T, Extra extends {} = {}> = { data: T, ok: "partial", error: any } & Extra;
4
+ export type ResultType<T, Extra extends {} = {}> = ErrorType<Extra> | SuccessType<T, Extra>;
5
+ export type PartialResultType<T, Extra extends {} = {}> = ErrorType<Extra> | SuccessType<T, Extra> | PartialType<T, Extra>;
6
+ export type CallbackResult<TData, TCallbackResult = void> = (result: ResultType<TData>) => TCallbackResult;
7
+ export type CallbackPartialResult<TData, TCallbackResult = void> = (result: PartialResultType<TData>) => TCallbackResult;
8
+
9
+
10
+ type IdentifiedType = { id: string }
11
+ export type PluginEventErrorType = ErrorType<IdentifiedType>;
12
+ export type PluginEventSuccessType<T> = SuccessType<T, IdentifiedType>;
13
+ export type PluginEventPartialType<T> = PartialType<T, IdentifiedType>;
14
+ export type PluginEventResultType<T> = PluginEventErrorType | PluginEventSuccessType<T>;
15
+ export type PluginEventPartialResultType<T> = PluginEventErrorType | PluginEventSuccessType<T> | PluginEventPartialType<T>;
16
+ export type PluginEventCallbackResult<TData, TCallbackResult = void> = (result: PluginEventResultType<TData>) => TCallbackResult;
17
+ export type PluginEventCallbackPartialResult<TData, TCallbackResult = void> = (result: PluginEventPartialResultType<TData>) => TCallbackResult;
@@ -0,0 +1,15 @@
1
+ import { Result } from "./Result";
2
+ import { CallbackResult } from "./types";
3
+
4
+ export function toPromise<T>(fn: (callback: CallbackResult<T>) => void) {
5
+ return new Promise<T>((resolve, reject) => {
6
+ fn((r) => {
7
+ if (r.ok === Result.ERROR) {
8
+ reject(r.error);
9
+ return;
10
+ }
11
+
12
+ resolve(r.data);
13
+ });
14
+ });
15
+ }