@effect-app/infra 4.0.0-beta.315 → 4.0.0-beta.317

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 (46) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/dist/Store/Cosmos/query.d.ts +2 -1
  3. package/dist/Store/Cosmos/query.d.ts.map +1 -1
  4. package/dist/Store/Cosmos/query.js +60 -2
  5. package/dist/Store/Cosmos.d.ts.map +1 -1
  6. package/dist/Store/Cosmos.js +17 -12
  7. package/dist/Store/Disk.d.ts.map +1 -1
  8. package/dist/Store/Disk.js +12 -7
  9. package/dist/Store/Memory.d.ts +2 -1
  10. package/dist/Store/Memory.d.ts.map +1 -1
  11. package/dist/Store/Memory.js +28 -15
  12. package/dist/Store/SQL/Pg.d.ts.map +1 -1
  13. package/dist/Store/SQL/Pg.js +15 -11
  14. package/dist/Store/SQL/query.d.ts +5 -1
  15. package/dist/Store/SQL/query.d.ts.map +1 -1
  16. package/dist/Store/SQL/query.js +131 -2
  17. package/dist/Store/SQL.d.ts +1 -1
  18. package/dist/Store/SQL.d.ts.map +1 -1
  19. package/dist/Store/SQL.js +24 -18
  20. package/dist/Store/codeFilter.d.ts.map +1 -1
  21. package/dist/Store/codeFilter.js +67 -20
  22. package/dist/Store/jsonDocument.d.ts +13 -0
  23. package/dist/Store/jsonDocument.d.ts.map +1 -0
  24. package/dist/Store/jsonDocument.js +31 -0
  25. package/dist/Store/utils.d.ts +16 -0
  26. package/dist/Store/utils.d.ts.map +1 -1
  27. package/dist/Store/utils.js +245 -6
  28. package/dist/logger.d.ts +5 -5
  29. package/examples/query.ts +4 -4
  30. package/package.json +3 -3
  31. package/src/Store/Cosmos/query.ts +65 -9
  32. package/src/Store/Cosmos.ts +17 -11
  33. package/src/Store/Disk.ts +28 -7
  34. package/src/Store/Memory.ts +40 -17
  35. package/src/Store/SQL/Pg.ts +23 -10
  36. package/src/Store/SQL/query.ts +152 -7
  37. package/src/Store/SQL.ts +37 -17
  38. package/src/Store/codeFilter.ts +71 -23
  39. package/src/Store/jsonDocument.ts +43 -0
  40. package/src/Store/utils.ts +275 -5
  41. package/test/cosmos-query.test.ts +100 -5
  42. package/test/dist/json-lower.test.d.ts.map +1 -0
  43. package/test/dist/query.test.d.ts.map +1 -1
  44. package/test/json-lower.test.ts +115 -0
  45. package/test/query.test.ts +261 -12
  46. package/test/sql-store.test.ts +233 -39
@@ -1,7 +1,246 @@
1
1
  import crypto from "crypto";
2
2
  import * as Effect from "effect-app/Effect";
3
3
  import * as Option from "effect-app/Option";
4
+ import * as S from "effect-app/Schema";
5
+ import * as SchemaAST from "effect-app/SchemaAST";
4
6
  import { OptimisticConcurrencyException } from "../errors.js";
7
+ const dateJson = S.toCodecJson(S.Date);
8
+ const isPlainObject = (value) => {
9
+ if (value === null || typeof value !== "object" || Array.isArray(value))
10
+ return false;
11
+ if (value instanceof Date || value instanceof Map || value instanceof Set)
12
+ return false;
13
+ const proto = Object.getPrototypeOf(value);
14
+ return proto === Object.prototype || proto === null;
15
+ };
16
+ const unwrapAst = (ast) => SchemaAST.isSuspend(ast) ? unwrapAst(ast.thunk()) : ast;
17
+ const unionAst = (hits) => {
18
+ if (hits.length === 0)
19
+ return undefined;
20
+ if (hits.length === 1)
21
+ return hits[0];
22
+ return S.Union(hits.map((hit) => S.make(hit))).ast;
23
+ };
24
+ const encodedObjects = (ast) => {
25
+ const current = unwrapAst(ast);
26
+ if (SchemaAST.isObjects(current))
27
+ return current;
28
+ if (SchemaAST.isDeclaration(current)) {
29
+ const encoded = unwrapAst(SchemaAST.toEncoded(current));
30
+ if (SchemaAST.isObjects(encoded))
31
+ return encoded;
32
+ }
33
+ return undefined;
34
+ };
35
+ const astAtPath = (ast, path) => {
36
+ if (ast === undefined)
37
+ return undefined;
38
+ if (path.length === 0)
39
+ return unwrapAst(ast);
40
+ const current = unwrapAst(ast);
41
+ const [head, ...tail] = path;
42
+ if (head === undefined)
43
+ return current;
44
+ if (SchemaAST.isUnion(current)) {
45
+ return unionAst(current.types.flatMap((member) => {
46
+ const hit = astAtPath(member, path);
47
+ return hit === undefined ? [] : [hit];
48
+ }));
49
+ }
50
+ if (head === "-1" || /^\d+$/.test(head)) {
51
+ if (SchemaAST.isArrays(current)) {
52
+ const element = current.rest[0] ?? current.elements[Number(head)] ?? current.elements[0];
53
+ return astAtPath(element, tail);
54
+ }
55
+ if (SchemaAST.isDeclaration(current) && current.typeParameters.length === 1) {
56
+ return astAtPath(current.typeParameters[0], tail);
57
+ }
58
+ return undefined;
59
+ }
60
+ const objects = encodedObjects(current);
61
+ if (objects !== undefined) {
62
+ const property = objects.propertySignatures.find((p) => p.name === head);
63
+ return property === undefined ? undefined : astAtPath(property.type, tail);
64
+ }
65
+ return undefined;
66
+ };
67
+ const elementAst = (ast) => {
68
+ if (ast === undefined)
69
+ return undefined;
70
+ const current = unwrapAst(ast);
71
+ if (SchemaAST.isUnion(current)) {
72
+ return unionAst(current.types.flatMap((member) => {
73
+ const hit = elementAst(member);
74
+ return hit === undefined ? [] : [hit];
75
+ }));
76
+ }
77
+ if (SchemaAST.isArrays(current))
78
+ return unwrapAst(current.rest[0] ?? current.elements[0] ?? current);
79
+ if (SchemaAST.isDeclaration(current) && current.typeParameters.length === 1) {
80
+ return unwrapAst(current.typeParameters[0]);
81
+ }
82
+ return current;
83
+ };
84
+ const mapKeyAst = (ast) => {
85
+ if (ast === undefined)
86
+ return undefined;
87
+ const current = unwrapAst(ast);
88
+ if (SchemaAST.isUnion(current)) {
89
+ return unionAst(current.types.flatMap((member) => {
90
+ const hit = mapKeyAst(member);
91
+ return hit === undefined ? [] : [hit];
92
+ }));
93
+ }
94
+ if (SchemaAST.isDeclaration(current) && current.typeParameters.length >= 2) {
95
+ return unwrapAst(current.typeParameters[0]);
96
+ }
97
+ return current;
98
+ };
99
+ const mapValueAst = (ast) => {
100
+ if (ast === undefined)
101
+ return undefined;
102
+ const current = unwrapAst(ast);
103
+ if (SchemaAST.isUnion(current)) {
104
+ return unionAst(current.types.flatMap((member) => {
105
+ const hit = mapValueAst(member);
106
+ return hit === undefined ? [] : [hit];
107
+ }));
108
+ }
109
+ if (SchemaAST.isDeclaration(current) && current.typeParameters.length >= 2) {
110
+ return unwrapAst(current.typeParameters[1]);
111
+ }
112
+ return current;
113
+ };
114
+ const asArray = (value) => Array.isArray(value) ? value : value instanceof Set ? [...value] : [value];
115
+ const encodeJson = (ast, value) => {
116
+ if (ast === undefined)
117
+ return toJsonQueryValue(value);
118
+ const current = unwrapAst(ast);
119
+ if (isPlainObject(value)) {
120
+ const out = {};
121
+ for (const [key, child] of Object.entries(value)) {
122
+ out[key] = encodeJson(astAtPath(current, [key]), child);
123
+ }
124
+ return out;
125
+ }
126
+ if (Array.isArray(value)) {
127
+ const element = SchemaAST.isArrays(current) || SchemaAST.isUnion(current)
128
+ ? elementAst(current)
129
+ : current;
130
+ return value.map((item) => encodeJson(element, item));
131
+ }
132
+ if (value instanceof Set) {
133
+ return [...value].map((item) => encodeJson(elementAst(current), item));
134
+ }
135
+ if (value instanceof Map) {
136
+ return [...value.entries()].map(([k, v]) => [
137
+ encodeJson(mapKeyAst(current), k),
138
+ encodeJson(mapValueAst(current), v)
139
+ ]);
140
+ }
141
+ return Effect.runSync(S.encodeUnknownEffect(S.toCodecJson(S.make(current)))(value));
142
+ };
143
+ const encodeFilterValue = (fieldAst, op, value) => {
144
+ if (fieldAst === undefined)
145
+ return toJsonQueryValue(value);
146
+ if (op === "in" || op === "notIn") {
147
+ return asArray(value).map((item) => encodeJson(fieldAst, item));
148
+ }
149
+ if (op === "includes"
150
+ || op === "notIncludes"
151
+ || op === "includes-any"
152
+ || op === "notIncludes-any"
153
+ || op === "includes-all"
154
+ || op === "notIncludes-all") {
155
+ const element = elementAst(fieldAst);
156
+ return op === "includes" || op === "notIncludes"
157
+ ? encodeJson(element, value)
158
+ : asArray(value).map((item) => encodeJson(element, item));
159
+ }
160
+ if (op === "hasKeyValue"
161
+ || op === "notHasKeyValue"
162
+ || op === "hasKeyValue-any"
163
+ || op === "notHasKeyValue-any"
164
+ || op === "hasKeyValue-all"
165
+ || op === "notHasKeyValue-all") {
166
+ const keyAst = mapKeyAst(fieldAst);
167
+ const valueAst = mapValueAst(fieldAst);
168
+ const pair = (item) => Array.isArray(item) && item.length >= 2
169
+ ? [encodeJson(keyAst, item[0]), encodeJson(valueAst, item[1])]
170
+ : toJsonQueryValue(item);
171
+ return op === "hasKeyValue" || op === "notHasKeyValue" ? pair(value) : asArray(value).map(pair);
172
+ }
173
+ if (op === "hasKey"
174
+ || op === "notHasKey"
175
+ || op === "hasKey-any"
176
+ || op === "notHasKey-any"
177
+ || op === "hasKey-all"
178
+ || op === "notHasKey-all") {
179
+ const keyAst = mapKeyAst(fieldAst);
180
+ return op === "hasKey" || op === "notHasKey"
181
+ ? encodeJson(keyAst, value)
182
+ : asArray(value).map((item) => encodeJson(keyAst, item));
183
+ }
184
+ if (op === "hasValue"
185
+ || op === "notHasValue"
186
+ || op === "hasValue-any"
187
+ || op === "notHasValue-any"
188
+ || op === "hasValue-all"
189
+ || op === "notHasValue-all") {
190
+ const valueAst = mapValueAst(fieldAst);
191
+ return op === "hasValue" || op === "notHasValue"
192
+ ? encodeJson(valueAst, value)
193
+ : asArray(value).map((item) => encodeJson(valueAst, item));
194
+ }
195
+ return encodeJson(fieldAst, value);
196
+ };
197
+ /**
198
+ * Lower Date / Map / Set to JSON when no field schema is available.
199
+ * Prefer {@link encodeWithSchema} / {@link jsonifyFilter} with the store schema.
200
+ */
201
+ export function toJsonQueryValue(value) {
202
+ if (value instanceof Date) {
203
+ return S.encodeSync(dateJson)(value);
204
+ }
205
+ if (value instanceof Map) {
206
+ return [...value.entries()].map(([k, v]) => [toJsonQueryValue(k), toJsonQueryValue(v)]);
207
+ }
208
+ if (value instanceof Set) {
209
+ return [...value].map((v) => toJsonQueryValue(v));
210
+ }
211
+ if (Array.isArray(value)) {
212
+ return value.map((v) => toJsonQueryValue(v));
213
+ }
214
+ if (isPlainObject(value)) {
215
+ const out = {};
216
+ for (const [k, v] of Object.entries(value)) {
217
+ out[k] = toJsonQueryValue(v);
218
+ }
219
+ return out;
220
+ }
221
+ if (value !== null && typeof value === "object") {
222
+ const toJSON = value.toJSON;
223
+ if (typeof toJSON === "function") {
224
+ return toJsonQueryValue(toJSON.call(value));
225
+ }
226
+ }
227
+ return value;
228
+ }
229
+ export function encodeWithSchema(schema, value) {
230
+ if (schema === undefined)
231
+ return toJsonQueryValue(value);
232
+ return encodeJson(SchemaAST.toEncoded(schema.ast), value);
233
+ }
234
+ export function jsonifyFilter(filter, schema) {
235
+ const ast = schema === undefined ? undefined : SchemaAST.toEncoded(schema.ast);
236
+ return filter.map((r) => r.t === "and-scope" || r.t === "or-scope" || r.t === "where-scope"
237
+ ? { ...r, result: jsonifyFilter(r.result, schema) }
238
+ : { ...r, value: encodeFilterValue(astAtPath(ast, r.path.split(".")), r.op, r.value) });
239
+ }
240
+ export const makeJsonLower = (config) => ({
241
+ toJson: (value) => encodeWithSchema(config?.schema, value),
242
+ jsonifyFilter: (filter) => jsonifyFilter(filter, config?.schema)
243
+ });
5
244
  /** Traverse an object by a dot-separated path string, e.g. `"a.b.c"`. */
6
245
  export function get(obj, path) {
7
246
  return path.split(".").reduce((res, key) => (res != null ? res[key] : res), obj);
@@ -41,18 +280,18 @@ export function lowercaseIfString(val) {
41
280
  return val;
42
281
  }
43
282
  export function compare(valA, valB) {
44
- return valA === valB;
283
+ return toJsonQueryValue(valA) === toJsonQueryValue(valB);
45
284
  }
46
285
  export function lowerThan(valA, valB) {
47
- return valA < valB;
286
+ return toJsonQueryValue(valA) < toJsonQueryValue(valB);
48
287
  }
49
288
  export function lowerThanExclusive(valA, valB) {
50
- return valA <= valB;
289
+ return toJsonQueryValue(valA) <= toJsonQueryValue(valB);
51
290
  }
52
291
  export function greaterThan(valA, valB) {
53
- return valA > valB;
292
+ return toJsonQueryValue(valA) > toJsonQueryValue(valB);
54
293
  }
55
294
  export function greaterThanExclusive(valA, valB) {
56
- return valA >= valB;
295
+ return toJsonQueryValue(valA) >= toJsonQueryValue(valB);
57
296
  }
58
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvU3RvcmUvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFBO0FBQzNCLE9BQU8sS0FBSyxNQUFNLE1BQU0sbUJBQW1CLENBQUE7QUFDM0MsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQTtBQUUzQyxPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxjQUFjLENBQUE7QUFFN0QseUVBQXlFO0FBQ3pFLE1BQU0sVUFBVSxHQUFHLENBQUMsR0FBUSxFQUFFLElBQVk7SUFDeEMsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQVEsRUFBRSxHQUFXLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQTtBQUMvRixDQUFDO0FBRUQsTUFBTSxDQUFDLE1BQU0sUUFBUSxHQUFHLENBQ3RCLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxFQUFLLEVBQ2YsRUFBRSxDQUNMLENBQUM7SUFDQyxHQUFHLENBQUM7SUFDSix5R0FBeUc7SUFDekcsS0FBSyxFQUFFLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO0NBQzNFLENBQVEsQ0FBQTtBQUVYLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxDQUFDLElBQVksRUFBRSxFQUFFLENBQzdDLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLEVBQ3pCLENBQUksRUFDSixLQUFZLEVBQ1osT0FBeUI7SUFFekIsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWixJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUMzQixPQUFPLEtBQUssQ0FBQyxDQUFDLElBQUksOEJBQThCLENBQUM7Z0JBQy9DLElBQUk7Z0JBQ0osRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQVc7Z0JBQ3RCLE9BQU8sRUFBRSxFQUFFO2dCQUNYLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSztnQkFDZCxJQUFJLEVBQUUsR0FBRzthQUNWLENBQUMsQ0FBQTtRQUNKLENBQUM7SUFDSCxDQUFDO0lBQ0QsSUFBSSxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxLQUFLLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUM5RCxPQUFPLEtBQUssQ0FBQyxDQUFDLElBQUksOEJBQThCLENBQUM7WUFDL0MsSUFBSTtZQUNKLEVBQUUsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBVztZQUNsQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEtBQUssQ0FBQyxLQUFLO1lBQzVCLEtBQUssRUFBRSxDQUFDLENBQUMsS0FBSztZQUNkLElBQUksRUFBRSxHQUFHO1NBQ1YsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUNELE9BQU8sUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFBO0FBQ3BCLENBQUMsQ0FBQyxDQUFBO0FBRUosTUFBTSxVQUFVLGlCQUFpQixDQUFJLEdBQU07SUFDekMsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUM1QixPQUFPLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUMxQixDQUFDO0lBQ0QsT0FBTyxHQUFHLENBQUE7QUFDWixDQUFDO0FBRUQsTUFBTSxVQUFVLE9BQU8sQ0FBQyxJQUFhLEVBQUUsSUFBYTtJQUNsRCxPQUFPLElBQUksS0FBSyxJQUFJLENBQUE7QUFDdEIsQ0FBQztBQUVELE1BQU0sVUFBVSxTQUFTLENBQUMsSUFBc0IsRUFBRSxJQUFzQjtJQUN0RSxPQUFPLElBQUksR0FBRyxJQUFJLENBQUE7QUFDcEIsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxJQUFzQixFQUFFLElBQXNCO0lBQy9FLE9BQU8sSUFBSSxJQUFJLElBQUksQ0FBQTtBQUNyQixDQUFDO0FBRUQsTUFBTSxVQUFVLFdBQVcsQ0FBQyxJQUFzQixFQUFFLElBQXNCO0lBQ3hFLE9BQU8sSUFBSSxHQUFHLElBQUksQ0FBQTtBQUNwQixDQUFDO0FBRUQsTUFBTSxVQUFVLG9CQUFvQixDQUFDLElBQXNCLEVBQUUsSUFBc0I7SUFDakYsT0FBTyxJQUFJLElBQUksSUFBSSxDQUFBO0FBQ3JCLENBQUMifQ==
297
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvU3RvcmUvdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFBO0FBQzNCLE9BQU8sS0FBSyxNQUFNLE1BQU0sbUJBQW1CLENBQUE7QUFFM0MsT0FBTyxLQUFLLE1BQU0sTUFBTSxtQkFBbUIsQ0FBQTtBQUMzQyxPQUFPLEtBQUssQ0FBQyxNQUFNLG1CQUFtQixDQUFBO0FBQ3RDLE9BQU8sS0FBSyxTQUFTLE1BQU0sc0JBQXNCLENBQUE7QUFFakQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0sY0FBYyxDQUFBO0FBRTdELE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFBO0FBRXRDLE1BQU0sYUFBYSxHQUFHLENBQUMsS0FBYyxFQUFvQyxFQUFFO0lBQ3pFLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQTtJQUNyRixJQUFJLEtBQUssWUFBWSxJQUFJLElBQUksS0FBSyxZQUFZLEdBQUcsSUFBSSxLQUFLLFlBQVksR0FBRztRQUFFLE9BQU8sS0FBSyxDQUFBO0lBQ3ZGLE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDMUMsT0FBTyxLQUFLLEtBQUssTUFBTSxDQUFDLFNBQVMsSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFBO0FBQ3JELENBQUMsQ0FBQTtBQUVELE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBa0IsRUFBaUIsRUFBRSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxD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
package/dist/logger.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  export declare const InfraLogger: {
2
- logWarning: (...message: readonly any[]) => import("effect/Effect").Effect<void, never, never>;
3
- logError: (...message: readonly any[]) => import("effect/Effect").Effect<void, never, never>;
4
- logFatal: (...message: readonly any[]) => import("effect/Effect").Effect<void, never, never>;
5
- logInfo: (...message: readonly any[]) => import("effect/Effect").Effect<void, never, never>;
2
+ logWarning: (...message: ReadonlyArray<any>) => import("effect/Effect").Effect<void, never, never>;
3
+ logError: (...message: ReadonlyArray<any>) => import("effect/Effect").Effect<void, never, never>;
4
+ logFatal: (...message: ReadonlyArray<any>) => import("effect/Effect").Effect<void, never, never>;
5
+ logInfo: (...message: ReadonlyArray<any>) => import("effect/Effect").Effect<void, never, never>;
6
6
  logDebug: (...message: ReadonlyArray<any>) => import("effect/Effect").Effect<void, never, never>;
7
- logWithLevel: (level: import("effect/LogLevel").Severity, ...message: readonly any[]) => import("effect/Effect").Effect<void, never, never>;
7
+ logWithLevel: (level: import("effect/LogLevel").Severity, ...message: ReadonlyArray<any>) => import("effect/Effect").Effect<void, never, never>;
8
8
  };
9
9
  //# sourceMappingURL=logger.d.ts.map
package/examples/query.ts CHANGED
@@ -76,7 +76,7 @@ const program = Effect.gen(function*() {
76
76
  and("_tag", "Something"),
77
77
  or(
78
78
  where("displayName", "Riley"),
79
- and("n", "gt", "2021-01-01T00:00:00Z"), // TODO: work with To type translation, so Date?
79
+ and("n", "gt", new Date("2021-01-01T00:00:00Z")),
80
80
  and("_tag", "Something")
81
81
  ),
82
82
  order("displayName"),
@@ -90,7 +90,7 @@ const program = Effect.gen(function*() {
90
90
  and("_tag", "Something"),
91
91
  or(
92
92
  where("displayName", "Riley"),
93
- and("n", "gt", "2021-01-01T00:00:00Z"), // TODO: work with To type translation, so Date?
93
+ and("n", "gt", new Date("2021-01-01T00:00:00Z")),
94
94
  and("_tag", "Something")
95
95
  ),
96
96
  order("displayName"),
@@ -112,7 +112,7 @@ expectTypeOf(test1).toEqualTypeOf<
112
112
  readonly _tag: "Something"
113
113
  readonly id: string
114
114
  readonly displayName: string
115
- readonly n: string
115
+ readonly n: Date
116
116
  readonly union: {
117
117
  readonly _tag: "string"
118
118
  readonly value: string
@@ -129,7 +129,7 @@ expectTypeOf(testneq1).toEqualTypeOf<
129
129
  readonly _tag: "Something"
130
130
  readonly id: string
131
131
  readonly displayName: string
132
- readonly n: string
132
+ readonly n: Date
133
133
  readonly union: {
134
134
  readonly _tag: "number"
135
135
  readonly value: number
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@effect-app/infra",
3
- "version": "4.0.0-beta.315",
3
+ "version": "4.0.0-beta.317",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "repository": {
@@ -10,18 +10,18 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@faker-js/faker": "^8.4.1",
13
+ "@sentry/node": "10.55.0",
13
14
  "fast-check": "^4.9.0",
14
15
  "jose": "^6.2.3",
15
16
  "proper-lockfile": "^4.1.2",
16
17
  "pure-rand": "8.4.0",
17
18
  "query-string": "^9.4.0",
18
- "effect-app": "4.0.0-beta.315"
19
+ "effect-app": "4.0.0-beta.317"
19
20
  },
20
21
  "devDependencies": {
21
22
  "@azure/cosmos": "^4.9.3",
22
23
  "@azure/service-bus": "^7.9.5",
23
24
  "@effect/sql-sqlite-node": "4.0.0-beta.107",
24
- "@sentry/node": "10.55.0",
25
25
  "@sentry/opentelemetry": "10.55.0",
26
26
  "@types/better-sqlite3": "^7.6.13",
27
27
  "@types/node": "25.9.1",
@@ -9,6 +9,7 @@ import type { SupportedValues } from "effect-app/Store"
9
9
  import { assertUnreachable } from "effect-app/utils"
10
10
  import { InfraLogger } from "../../logger.ts"
11
11
  import { isRelationCheck } from "../codeFilter.ts"
12
+ import { jsonifyFilter, type JsonLower, toJsonQueryValue } from "../utils.ts"
12
13
 
13
14
  export function logQuery(q: {
14
15
  query: string
@@ -60,8 +61,12 @@ export function buildWhereCosmosQuery3(
60
61
  >,
61
62
  order?: NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }>,
62
63
  skip?: number,
63
- limit?: number
64
+ limit?: number,
65
+ json?: JsonLower
64
66
  ) {
67
+ const toJson = json?.toJson ?? toJsonQueryValue
68
+ filter = (json?.jsonifyFilter ?? jsonifyFilter)(filter)
69
+ defaultValues = toJson(defaultValues) as Record<string, unknown>
65
70
  const statement = (x: FilterR, i: number) => {
66
71
  if (x.path === idKey) {
67
72
  x = { ...x, path: "id" }
@@ -89,23 +94,56 @@ export function buildWhereCosmosQuery3(
89
94
  return `(NOT ARRAY_CONTAINS(${k}, ${v}))`
90
95
 
91
96
  case "includes-any":
92
- return `ARRAY_CONTAINS_ANY(${k}, ${
93
- (x.value as unknown as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
94
- })`
97
+ return `ARRAY_CONTAINS_ANY(${k}, ${(x.value as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")})`
95
98
  case "notIncludes-any":
96
99
  return `(NOT ARRAY_CONTAINS_ANY(${k}, ${
97
- (x.value as unknown as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
100
+ (x.value as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
98
101
  }))`
99
102
 
100
103
  case "includes-all":
101
- return `ARRAY_CONTAINS_ALL(${k}, ${
102
- (x.value as unknown as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
103
- })`
104
+ return `ARRAY_CONTAINS_ALL(${k}, ${(x.value as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")})`
104
105
  case "notIncludes-all":
105
106
  return `(NOT ARRAY_CONTAINS_ALL(${k}, ${
106
- (x.value as unknown as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
107
+ (x.value as readonly unknown[]).map((_, i) => `${v}__${i}`).join(", ")
107
108
  }))`
108
109
 
110
+ case "hasKey":
111
+ return `EXISTS(SELECT VALUE p FROM p IN ${k} WHERE p[0] = ${v})`
112
+ case "notHasKey":
113
+ return `(NOT EXISTS(SELECT VALUE p FROM p IN ${k} WHERE p[0] = ${v}))`
114
+ case "hasValue":
115
+ return `EXISTS(SELECT VALUE p FROM p IN ${k} WHERE p[1] = ${v})`
116
+ case "notHasValue":
117
+ return `(NOT EXISTS(SELECT VALUE p FROM p IN ${k} WHERE p[1] = ${v}))`
118
+ case "hasKeyValue":
119
+ return `ARRAY_CONTAINS(${k}, ${v})`
120
+ case "notHasKeyValue":
121
+ return `(NOT ARRAY_CONTAINS(${k}, ${v}))`
122
+ case "hasKey-any":
123
+ return `EXISTS(SELECT VALUE p FROM p IN ${k} WHERE ARRAY_CONTAINS(${v}, p[0]))`
124
+ case "notHasKey-any":
125
+ return `(NOT EXISTS(SELECT VALUE p FROM p IN ${k} WHERE ARRAY_CONTAINS(${v}, p[0])))`
126
+ case "hasKey-all":
127
+ return `(NOT EXISTS(SELECT VALUE key FROM key IN ${v} WHERE NOT EXISTS(SELECT VALUE p FROM p IN ${k} WHERE p[0] = key)))`
128
+ case "notHasKey-all":
129
+ return `EXISTS(SELECT VALUE key FROM key IN ${v} WHERE NOT EXISTS(SELECT VALUE p FROM p IN ${k} WHERE p[0] = key))`
130
+ case "hasValue-any":
131
+ return `EXISTS(SELECT VALUE p FROM p IN ${k} WHERE ARRAY_CONTAINS(${v}, p[1]))`
132
+ case "notHasValue-any":
133
+ return `(NOT EXISTS(SELECT VALUE p FROM p IN ${k} WHERE ARRAY_CONTAINS(${v}, p[1])))`
134
+ case "hasValue-all":
135
+ return `(NOT EXISTS(SELECT VALUE val FROM val IN ${v} WHERE NOT EXISTS(SELECT VALUE p FROM p IN ${k} WHERE p[1] = val)))`
136
+ case "notHasValue-all":
137
+ return `EXISTS(SELECT VALUE val FROM val IN ${v} WHERE NOT EXISTS(SELECT VALUE p FROM p IN ${k} WHERE p[1] = val))`
138
+ case "hasKeyValue-any":
139
+ return `EXISTS(SELECT VALUE pair FROM pair IN ${v} WHERE ARRAY_CONTAINS(${k}, pair))`
140
+ case "notHasKeyValue-any":
141
+ return `(NOT EXISTS(SELECT VALUE pair FROM pair IN ${v} WHERE ARRAY_CONTAINS(${k}, pair)))`
142
+ case "hasKeyValue-all":
143
+ return `(NOT EXISTS(SELECT VALUE pair FROM pair IN ${v} WHERE NOT ARRAY_CONTAINS(${k}, pair)))`
144
+ case "notHasKeyValue-all":
145
+ return `EXISTS(SELECT VALUE pair FROM pair IN ${v} WHERE NOT ARRAY_CONTAINS(${k}, pair))`
146
+
109
147
  case "contains":
110
148
  return `CONTAINS(${k}, ${v}, true)`
111
149
 
@@ -166,6 +204,24 @@ export function buildWhereCosmosQuery3(
166
204
  "notIncludes-any": "includes-any",
167
205
  "includes-all": "notIncludes-all",
168
206
  "notIncludes-all": "includes-all",
207
+ hasKey: "notHasKey",
208
+ notHasKey: "hasKey",
209
+ hasValue: "notHasValue",
210
+ notHasValue: "hasValue",
211
+ hasKeyValue: "notHasKeyValue",
212
+ notHasKeyValue: "hasKeyValue",
213
+ "hasKey-any": "notHasKey-any",
214
+ "notHasKey-any": "hasKey-any",
215
+ "hasKey-all": "notHasKey-all",
216
+ "notHasKey-all": "hasKey-all",
217
+ "hasValue-any": "notHasValue-any",
218
+ "notHasValue-any": "hasValue-any",
219
+ "hasValue-all": "notHasValue-all",
220
+ "notHasValue-all": "hasValue-all",
221
+ "hasKeyValue-any": "notHasKeyValue-any",
222
+ "notHasKeyValue-any": "hasKeyValue-any",
223
+ "hasKeyValue-all": "notHasKeyValue-all",
224
+ "notHasKeyValue-all": "hasKeyValue-all",
169
225
  in: "notIn",
170
226
  notIn: "in"
171
227
  } satisfies Record<Ops, Ops>
@@ -19,6 +19,8 @@ import { DatabaseError, OptimisticConcurrencyException } from "../errors.ts"
19
19
  import { InfraLogger } from "../logger.ts"
20
20
  import { annotateCosmosResponse, annotateDb } from "../otel.ts"
21
21
  import { buildWhereCosmosQuery3, logQuery } from "./Cosmos/query.ts"
22
+ import { makeJsonDocumentCodec } from "./jsonDocument.ts"
23
+ import { makeJsonLower } from "./utils.ts"
22
24
 
23
25
  const makeMapId =
24
26
  <IdKey extends keyof Encoded, Encoded extends FieldValues>(idKey: IdKey) => ({ [idKey]: id, ...e }: Encoded) => ({
@@ -96,6 +98,10 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
96
98
  ) {
97
99
  const mapId = makeMapId<IdKey, Encoded>(idKey)
98
100
  const mapReverseId = makeReverseMapId<IdKey, Encoded>(idKey)
101
+ const codec = makeJsonDocumentCodec<Encoded>(config?.schema)
102
+ const json = makeJsonLower(config)
103
+ const defaultValues = json.toJson(config?.defaultValues ?? {}) as Partial<Encoded>
104
+ const fromStored = (raw: Encoded) => codec.decode({ ...defaultValues, ...mapReverseId(raw as any) })
99
105
  type PM = PersistenceModelType<Encoded>
100
106
  type PMCosmos = PersistenceModelType<Omit<Encoded, IdKey> & { id: string }>
101
107
  const containerId = `${prefix}${name}`
@@ -128,7 +134,6 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
128
134
  return namespace
129
135
  }))
130
136
 
131
- const defaultValues = config?.defaultValues ?? {}
132
137
  const container = db.container(containerId)
133
138
  const bulk = container.items.bulk.bind(container.items)
134
139
  const execBatch = container.items.batch.bind(container.items)
@@ -205,7 +210,7 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
205
210
  dropUndefinedT({
206
211
  operationType: "Create" as const,
207
212
  resourceBody: {
208
- ...Struct.omit(x, ["_etag", idKey]),
213
+ ...Struct.omit(codec.encode(x), ["_etag", idKey]),
209
214
  id: x[idKey],
210
215
  _partitionKey: nsPartitionValue(ns, x)
211
216
  }
@@ -217,7 +222,7 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
217
222
  operationType: "Replace" as const,
218
223
  id: x[idKey],
219
224
  resourceBody: {
220
- ...Struct.omit(x, ["_etag", idKey]),
225
+ ...Struct.omit(codec.encode(x), ["_etag", idKey]),
221
226
  id: x[idKey],
222
227
  _partitionKey: nsPartitionValue(ns, x)
223
228
  },
@@ -314,7 +319,7 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
314
319
  onNone: () => ({
315
320
  operationType: "Create" as const,
316
321
  resourceBody: {
317
- ...Struct.omit(x, ["_etag", idKey]),
322
+ ...Struct.omit(codec.encode(x), ["_etag", idKey]),
318
323
  id: x[idKey],
319
324
  _partitionKey: nsPartitionValue(ns, x)
320
325
  }
@@ -325,7 +330,7 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
325
330
  operationType: "Replace" as const,
326
331
  id: x[idKey],
327
332
  resourceBody: {
328
- ...Struct.omit(x, ["_etag", idKey]),
333
+ ...Struct.omit(codec.encode(x), ["_etag", idKey]),
329
334
  id: x[idKey],
330
335
  _partitionKey: nsPartitionValue(ns, x)
331
336
  },
@@ -447,7 +452,7 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
447
452
  container.items.query<PMCosmos>(q, { partitionKey: nsBasePartitionKey(ns) }).fetchAll()
448
453
  )
449
454
  yield* annotateFeed(response)
450
- return response.resources.map((_) => ({ ...defaultValues, ...mapReverseId(_) }))
455
+ return response.resources.map((_) => fromStored(_ as unknown as Encoded))
451
456
  })
452
457
  .pipe(
453
458
  annotateDb({
@@ -492,7 +497,8 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
492
497
  | undefined,
493
498
  f.order as NonEmptyReadonlyArray<{ key: string; direction: "ASC" | "DESC" }> | undefined,
494
499
  skip,
495
- limit
500
+ limit,
501
+ json
496
502
  )
497
503
  ),
498
504
  ns: resolveNamespace
@@ -520,7 +526,7 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
520
526
  container.items.query<{ f: M }>(q, { partitionKey: nsBasePartitionKey(ns) }).fetchAll()
521
527
  )
522
528
  yield* annotateFeed(response)
523
- return response.resources.map(({ f }) => ({ ...defaultValues, ...mapReverseId(f as any) }) as any)
529
+ return response.resources.map(({ f }) => fromStored(f as Encoded) as any)
524
530
  })
525
531
  .pipe(
526
532
  annotateDb({
@@ -546,7 +552,7 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
546
552
  )
547
553
  yield* annotateItem(response)
548
554
  return Option.fromNullishOr(response.resource).pipe(
549
- Option.map((_) => ({ ...defaultValues, ...mapReverseId(_) }))
555
+ Option.map((_) => fromStored(_))
550
556
  )
551
557
  })
552
558
  .pipe(annotateDb({
@@ -573,12 +579,12 @@ const makeCosmosStore = Effect.fnUntraced(function*({ prefix }: StorageConfig) {
573
579
  {
574
580
  onNone: () =>
575
581
  container.items.create({
576
- ...mapId(e),
582
+ ...mapId(codec.encode(e)),
577
583
  _partitionKey: nsPartitionValue(ns, e)
578
584
  }),
579
585
  onSome: (eTag) =>
580
586
  container.item(e[idKey], nsPartitionValue(ns, e)).replace(
581
- { ...mapId(e), _partitionKey: nsPartitionValue(ns, e) },
587
+ { ...mapId(codec.encode(e)), _partitionKey: nsPartitionValue(ns, e) },
582
588
  {
583
589
  accessCondition: {
584
590
  type: "IfMatch",