@effect-app/infra 4.0.0-beta.12 → 4.0.0-beta.120
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/CHANGELOG.md +794 -0
- package/dist/CUPS.d.ts +3 -3
- package/dist/CUPS.d.ts.map +1 -1
- package/dist/CUPS.js +3 -3
- package/dist/Emailer/service.d.ts +3 -3
- package/dist/Emailer/service.d.ts.map +1 -1
- package/dist/Emailer/service.js +3 -3
- package/dist/MainFiberSet.d.ts +2 -2
- package/dist/MainFiberSet.d.ts.map +1 -1
- package/dist/MainFiberSet.js +3 -3
- package/dist/Model/Repository/Registry.d.ts +20 -0
- package/dist/Model/Repository/Registry.d.ts.map +1 -0
- package/dist/Model/Repository/Registry.js +17 -0
- package/dist/Model/Repository/internal/internal.d.ts +3 -3
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +22 -16
- package/dist/Model/Repository/makeRepo.d.ts +5 -4
- package/dist/Model/Repository/makeRepo.d.ts.map +1 -1
- package/dist/Model/Repository/makeRepo.js +4 -1
- package/dist/Model/Repository/service.d.ts +5 -0
- package/dist/Model/Repository/service.d.ts.map +1 -1
- package/dist/Model/Repository/validation.d.ts +7 -6
- package/dist/Model/Repository/validation.d.ts.map +1 -1
- package/dist/Model/Repository.d.ts +1 -0
- package/dist/Model/Repository.d.ts.map +1 -1
- package/dist/Model/Repository.js +2 -1
- package/dist/Model/query/dsl.d.ts +9 -9
- package/dist/Model.d.ts +1 -0
- package/dist/Model.d.ts.map +1 -1
- package/dist/Model.js +2 -1
- package/dist/Operations.d.ts +2 -2
- package/dist/Operations.d.ts.map +1 -1
- package/dist/Operations.js +3 -3
- package/dist/OperationsRepo.d.ts +3 -3
- package/dist/OperationsRepo.d.ts.map +1 -1
- package/dist/OperationsRepo.js +3 -3
- package/dist/QueueMaker/SQLQueue.d.ts +2 -4
- package/dist/QueueMaker/SQLQueue.d.ts.map +1 -1
- package/dist/QueueMaker/SQLQueue.js +8 -6
- package/dist/QueueMaker/errors.d.ts +1 -1
- package/dist/QueueMaker/errors.d.ts.map +1 -1
- package/dist/QueueMaker/memQueue.js +3 -3
- package/dist/QueueMaker/sbqueue.js +3 -3
- package/dist/RequestContext.d.ts +22 -17
- package/dist/RequestContext.d.ts.map +1 -1
- package/dist/RequestContext.js +5 -5
- package/dist/RequestFiberSet.d.ts +2 -2
- package/dist/RequestFiberSet.d.ts.map +1 -1
- package/dist/RequestFiberSet.js +5 -5
- package/dist/Store/ContextMapContainer.d.ts +19 -3
- package/dist/Store/ContextMapContainer.d.ts.map +1 -1
- package/dist/Store/ContextMapContainer.js +13 -3
- package/dist/Store/Cosmos.d.ts.map +1 -1
- package/dist/Store/Cosmos.js +136 -68
- package/dist/Store/Disk.d.ts.map +1 -1
- package/dist/Store/Disk.js +24 -21
- package/dist/Store/Memory.d.ts +2 -2
- package/dist/Store/Memory.d.ts.map +1 -1
- package/dist/Store/Memory.js +26 -21
- package/dist/Store/SQL/Pg.d.ts +4 -0
- package/dist/Store/SQL/Pg.d.ts.map +1 -0
- package/dist/Store/SQL/Pg.js +191 -0
- package/dist/Store/SQL/query.d.ts +38 -0
- package/dist/Store/SQL/query.d.ts.map +1 -0
- package/dist/Store/SQL/query.js +367 -0
- package/dist/Store/SQL.d.ts +20 -0
- package/dist/Store/SQL.d.ts.map +1 -0
- package/dist/Store/SQL.js +381 -0
- package/dist/Store/index.d.ts +4 -1
- package/dist/Store/index.d.ts.map +1 -1
- package/dist/Store/index.js +15 -3
- package/dist/Store/service.d.ts +16 -5
- package/dist/Store/service.d.ts.map +1 -1
- package/dist/Store/service.js +24 -6
- package/dist/adapters/ServiceBus.d.ts +6 -6
- package/dist/adapters/ServiceBus.d.ts.map +1 -1
- package/dist/adapters/ServiceBus.js +9 -9
- package/dist/adapters/cosmos-client.d.ts +2 -2
- package/dist/adapters/cosmos-client.d.ts.map +1 -1
- package/dist/adapters/cosmos-client.js +3 -3
- package/dist/adapters/logger.d.ts.map +1 -1
- package/dist/adapters/memQueue.d.ts +2 -2
- package/dist/adapters/memQueue.d.ts.map +1 -1
- package/dist/adapters/memQueue.js +3 -3
- package/dist/adapters/mongo-client.d.ts +2 -2
- package/dist/adapters/mongo-client.d.ts.map +1 -1
- package/dist/adapters/mongo-client.js +3 -3
- package/dist/adapters/redis-client.d.ts +3 -3
- package/dist/adapters/redis-client.d.ts.map +1 -1
- package/dist/adapters/redis-client.js +3 -3
- package/dist/api/ContextProvider.d.ts +6 -6
- package/dist/api/ContextProvider.d.ts.map +1 -1
- package/dist/api/ContextProvider.js +6 -6
- package/dist/api/internal/auth.d.ts +1 -1
- package/dist/api/internal/events.d.ts +2 -2
- package/dist/api/internal/events.d.ts.map +1 -1
- package/dist/api/internal/events.js +11 -7
- package/dist/api/layerUtils.d.ts +5 -5
- package/dist/api/layerUtils.d.ts.map +1 -1
- package/dist/api/layerUtils.js +5 -5
- package/dist/api/routing/middleware/RouterMiddleware.d.ts +3 -3
- package/dist/api/routing/middleware/RouterMiddleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.d.ts +35 -1
- package/dist/api/routing/middleware/middleware.d.ts.map +1 -1
- package/dist/api/routing/middleware/middleware.js +39 -1
- package/dist/api/routing.d.ts +1 -5
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +3 -2
- package/dist/api/setupRequest.d.ts +6 -3
- package/dist/api/setupRequest.d.ts.map +1 -1
- package/dist/api/setupRequest.js +11 -6
- package/dist/logger.d.ts.map +1 -1
- package/examples/query.ts +30 -26
- package/package.json +36 -18
- package/src/CUPS.ts +2 -2
- package/src/Emailer/service.ts +2 -2
- package/src/MainFiberSet.ts +2 -2
- package/src/Model/Repository/Registry.ts +33 -0
- package/src/Model/Repository/internal/internal.ts +76 -59
- package/src/Model/Repository/makeRepo.ts +7 -4
- package/src/Model/Repository/service.ts +6 -0
- package/src/Model/Repository.ts +1 -0
- package/src/Model.ts +1 -0
- package/src/Operations.ts +2 -2
- package/src/OperationsRepo.ts +2 -2
- package/src/QueueMaker/SQLQueue.ts +8 -7
- package/src/QueueMaker/memQueue.ts +2 -2
- package/src/QueueMaker/sbqueue.ts +2 -2
- package/src/RequestContext.ts +4 -4
- package/src/RequestFiberSet.ts +4 -4
- package/src/Store/ContextMapContainer.ts +41 -2
- package/src/Store/Cosmos.ts +350 -255
- package/src/Store/Disk.ts +37 -33
- package/src/Store/Memory.ts +29 -22
- package/src/Store/SQL/Pg.ts +321 -0
- package/src/Store/SQL/query.ts +409 -0
- package/src/Store/SQL.ts +674 -0
- package/src/Store/index.ts +17 -2
- package/src/Store/service.ts +31 -7
- package/src/adapters/ServiceBus.ts +8 -8
- package/src/adapters/cosmos-client.ts +2 -2
- package/src/adapters/memQueue.ts +2 -2
- package/src/adapters/mongo-client.ts +2 -2
- package/src/adapters/redis-client.ts +2 -2
- package/src/api/ContextProvider.ts +11 -11
- package/src/api/internal/events.ts +14 -9
- package/src/api/layerUtils.ts +8 -8
- package/src/api/routing/middleware/RouterMiddleware.ts +4 -4
- package/src/api/routing/middleware/middleware.ts +43 -0
- package/src/api/routing.ts +3 -3
- package/src/api/setupRequest.ts +27 -7
- package/test/contextProvider.test.ts +11 -11
- package/test/controller.test.ts +12 -9
- package/test/dist/contextProvider.test.d.ts.map +1 -1
- package/test/dist/controller.test.d.ts.map +1 -1
- package/test/dist/date-query.test.d.ts.map +1 -0
- package/test/dist/fixtures.d.ts +19 -9
- package/test/dist/fixtures.d.ts.map +1 -1
- package/test/dist/fixtures.js +11 -9
- package/test/dist/query.test.d.ts.map +1 -1
- package/test/dist/rawQuery.test.d.ts.map +1 -1
- package/test/dist/requires.test.d.ts.map +1 -1
- package/test/dist/rpc-multi-middleware.test.d.ts.map +1 -1
- package/test/dist/sql-store.test.d.ts.map +1 -0
- package/test/fixtures.ts +10 -8
- package/test/query.test.ts +182 -33
- package/test/rawQuery.test.ts +22 -18
- package/test/requires.test.ts +6 -5
- package/test/rpc-multi-middleware.test.ts +72 -3
- package/test/sql-store.test.ts +1064 -0
- package/test/validateSample.test.ts +12 -9
- package/tsconfig.json +0 -1
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { Context, Layer, LayerMap } from "effect";
|
|
3
|
+
import { Effect, Option, Struct } from "effect-app";
|
|
4
|
+
import { toNonEmptyArray } from "effect-app/Array";
|
|
5
|
+
import { SqlClient } from "effect/unstable/sql";
|
|
6
|
+
import { OptimisticConcurrencyException } from "../errors.js";
|
|
7
|
+
import { InfraLogger } from "../logger.js";
|
|
8
|
+
import { storeId } from "./Memory.js";
|
|
9
|
+
import { StoreMaker } from "./service.js";
|
|
10
|
+
import { buildWhereSQLQuery, logQuery, sqliteDialect } from "./SQL/query.js";
|
|
11
|
+
import { makeETag } from "./utils.js";
|
|
12
|
+
export class WithNsTransaction extends Context.Service()("effect-app/WithNsTransaction") {
|
|
13
|
+
}
|
|
14
|
+
/** @internal */
|
|
15
|
+
export const parseRow = (row, idKey, defaultValues) => {
|
|
16
|
+
const data = (typeof row.data === "string" ? JSON.parse(row.data) : row.data);
|
|
17
|
+
return { ...defaultValues, ...data, [idKey]: row.id, _etag: row._etag ?? undefined };
|
|
18
|
+
};
|
|
19
|
+
const parseSelectRow = (row, idKey) => {
|
|
20
|
+
const result = {};
|
|
21
|
+
for (const [key, value] of Object.entries(row)) {
|
|
22
|
+
if (key === "id") {
|
|
23
|
+
result[idKey] = value;
|
|
24
|
+
result["id"] = value;
|
|
25
|
+
}
|
|
26
|
+
else if (typeof value === "string") {
|
|
27
|
+
try {
|
|
28
|
+
result[key] = JSON.parse(value);
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
result[key] = value;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
result[key] = value;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
function makeSQLStoreInt(dialect, jsonColumnType) {
|
|
41
|
+
return ({ prefix }) => Effect.gen(function* () {
|
|
42
|
+
const sql = yield* SqlClient.SqlClient;
|
|
43
|
+
return {
|
|
44
|
+
make: (name, idKey, seed, config) => Effect.gen(function* () {
|
|
45
|
+
const tableName = `${prefix}${name}`;
|
|
46
|
+
const defaultValues = config?.defaultValues ?? {};
|
|
47
|
+
const resolveNamespace = !config?.allowNamespace
|
|
48
|
+
? Effect.succeed("primary")
|
|
49
|
+
: storeId.asEffect().pipe(Effect.map((namespace) => {
|
|
50
|
+
if (namespace !== "primary" && !config.allowNamespace(namespace)) {
|
|
51
|
+
throw new Error(`Namespace ${namespace} not allowed!`);
|
|
52
|
+
}
|
|
53
|
+
return namespace;
|
|
54
|
+
}));
|
|
55
|
+
const ensureTable = sql
|
|
56
|
+
.unsafe(`CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL, _namespace TEXT NOT NULL DEFAULT 'primary', _etag TEXT, data ${jsonColumnType} NOT NULL, PRIMARY KEY (id, _namespace))`)
|
|
57
|
+
.pipe(Effect.andThen(sql.unsafe(`CREATE TABLE IF NOT EXISTS "_migrations" (id TEXT NOT NULL, version TEXT NOT NULL, PRIMARY KEY (id, version))`)), Effect.orDie, Effect.asVoid);
|
|
58
|
+
const toRow = (e) => {
|
|
59
|
+
const newE = makeETag(e);
|
|
60
|
+
const id = newE[idKey];
|
|
61
|
+
const { _etag, [idKey]: _id, ...rest } = newE;
|
|
62
|
+
const data = JSON.stringify(rest);
|
|
63
|
+
return { id, _etag: newE._etag, data, item: newE };
|
|
64
|
+
};
|
|
65
|
+
const exec = (query, params) => sql.unsafe(query, params).pipe(Effect.orDie);
|
|
66
|
+
const setInternal = (e, ns) => Effect.gen(function* () {
|
|
67
|
+
const row = toRow(e);
|
|
68
|
+
if (e._etag) {
|
|
69
|
+
yield* exec(`UPDATE "${tableName}" SET _etag = ?, data = ? WHERE id = ? AND _etag = ? AND _namespace = ?`, [row._etag, row.data, row.id, e._etag, ns]);
|
|
70
|
+
const existing = yield* exec(`SELECT _etag FROM "${tableName}" WHERE id = ? AND _namespace = ?`, [row.id, ns]);
|
|
71
|
+
const current = existing[0];
|
|
72
|
+
if (!current || current._etag !== row._etag) {
|
|
73
|
+
if (current) {
|
|
74
|
+
return yield* new OptimisticConcurrencyException({
|
|
75
|
+
type: name,
|
|
76
|
+
id: row.id,
|
|
77
|
+
current: current._etag,
|
|
78
|
+
found: e._etag,
|
|
79
|
+
code: 412
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return yield* new OptimisticConcurrencyException({
|
|
83
|
+
type: name,
|
|
84
|
+
id: row.id,
|
|
85
|
+
current: "",
|
|
86
|
+
found: e._etag,
|
|
87
|
+
code: 404
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
yield* exec(`INSERT INTO "${tableName}" (id, _namespace, _etag, data) VALUES (?, ?, ?, ?)`, [row.id, ns, row._etag, row.data]);
|
|
93
|
+
}
|
|
94
|
+
return row.item;
|
|
95
|
+
});
|
|
96
|
+
const bulkSetInternal = (items, ns) => sql
|
|
97
|
+
.withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
|
|
98
|
+
.pipe(Effect.orDie, Effect.map((_) => _));
|
|
99
|
+
const ctx = yield* Effect.context();
|
|
100
|
+
const seedCache = new Map();
|
|
101
|
+
const makeSeedEffect = Effect.fnUntraced(function* (ns) {
|
|
102
|
+
yield* ensureTable;
|
|
103
|
+
if (!seed)
|
|
104
|
+
return;
|
|
105
|
+
const existing = yield* exec(`SELECT id FROM "_migrations" WHERE id = ? AND version = ?`, [`${tableName}::${ns}`, tableName]);
|
|
106
|
+
if (existing.length > 0)
|
|
107
|
+
return;
|
|
108
|
+
yield* InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`);
|
|
109
|
+
const items = yield* seed.pipe(Effect.provide(ctx), Effect.orDie);
|
|
110
|
+
const ne = toNonEmptyArray([...items]);
|
|
111
|
+
if (Option.isSome(ne))
|
|
112
|
+
yield* bulkSetInternal(ne.value, ns);
|
|
113
|
+
yield* exec(`INSERT INTO "_migrations" (id, version) VALUES (?, ?)`, [`${tableName}::${ns}`, tableName]);
|
|
114
|
+
});
|
|
115
|
+
const seedNamespace = (ns) => {
|
|
116
|
+
let cached = seedCache.get(ns);
|
|
117
|
+
if (!cached) {
|
|
118
|
+
cached = Effect.cached(Effect.uninterruptible(makeSeedEffect(ns))).pipe(Effect.runSync);
|
|
119
|
+
seedCache.set(ns, cached);
|
|
120
|
+
}
|
|
121
|
+
return cached;
|
|
122
|
+
};
|
|
123
|
+
const s = {
|
|
124
|
+
seedNamespace: (ns) => seedNamespace(ns),
|
|
125
|
+
all: resolveNamespace.pipe(Effect.flatMap((ns) => exec(`SELECT id, _etag, data FROM "${tableName}" WHERE _namespace = ?`, [ns])
|
|
126
|
+
.pipe(Effect.map((rows) => rows.map((r) => parseRow(r, idKey, defaultValues))), Effect.withSpan("SQL.all [effect-app/infra/Store]", {
|
|
127
|
+
attributes: {
|
|
128
|
+
"repository.table_name": tableName,
|
|
129
|
+
"repository.model_name": name,
|
|
130
|
+
"repository.namespace": ns
|
|
131
|
+
}
|
|
132
|
+
}, { captureStackTrace: false })))),
|
|
133
|
+
find: (id) => resolveNamespace.pipe(Effect.flatMap((ns) => exec(`SELECT id, _etag, data FROM "${tableName}" WHERE id = ? AND _namespace = ?`, [id, ns])
|
|
134
|
+
.pipe(Effect.map((rows) => {
|
|
135
|
+
const row = rows[0];
|
|
136
|
+
return row
|
|
137
|
+
? Option.some(parseRow(row, idKey, defaultValues))
|
|
138
|
+
: Option.none();
|
|
139
|
+
}), Effect.withSpan("SQL.find [effect-app/infra/Store]", {
|
|
140
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name, id }
|
|
141
|
+
}, { captureStackTrace: false })))),
|
|
142
|
+
filter: (f) => {
|
|
143
|
+
const filter = f
|
|
144
|
+
.filter;
|
|
145
|
+
return resolveNamespace
|
|
146
|
+
.pipe(Effect
|
|
147
|
+
.flatMap((ns) => Effect
|
|
148
|
+
.sync(() => {
|
|
149
|
+
const q = buildWhereSQLQuery(dialect, idKey, filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [], tableName, defaultValues, f
|
|
150
|
+
.select, f
|
|
151
|
+
.order, f
|
|
152
|
+
.skip, f
|
|
153
|
+
.limit);
|
|
154
|
+
const hasWhere = q
|
|
155
|
+
.sql
|
|
156
|
+
.includes("WHERE");
|
|
157
|
+
const nsSql = hasWhere
|
|
158
|
+
? q
|
|
159
|
+
.sql
|
|
160
|
+
.replace("WHERE", `WHERE _namespace = ? AND`)
|
|
161
|
+
: q
|
|
162
|
+
.sql
|
|
163
|
+
.replace(`FROM "${tableName}"`, `FROM "${tableName}" WHERE _namespace = ?`);
|
|
164
|
+
return {
|
|
165
|
+
sql: nsSql,
|
|
166
|
+
params: [
|
|
167
|
+
ns,
|
|
168
|
+
...q
|
|
169
|
+
.params
|
|
170
|
+
]
|
|
171
|
+
};
|
|
172
|
+
})
|
|
173
|
+
.pipe(Effect
|
|
174
|
+
.tap((q) => logQuery(q)), Effect.flatMap((q) => exec(q.sql, q.params).pipe(Effect.map((rows) => {
|
|
175
|
+
if (f.select) {
|
|
176
|
+
return rows.map((r) => {
|
|
177
|
+
const selected = parseSelectRow(r, idKey);
|
|
178
|
+
return {
|
|
179
|
+
...Struct.pick(defaultValues, f.select.filter((_) => typeof _ === "string")),
|
|
180
|
+
...selected
|
|
181
|
+
};
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return rows.map((r) => parseRow(r, idKey, defaultValues));
|
|
185
|
+
}))), Effect.withSpan("SQL.filter [effect-app/infra/Store]", {
|
|
186
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
187
|
+
}, { captureStackTrace: false }))));
|
|
188
|
+
},
|
|
189
|
+
set: (e) => resolveNamespace.pipe(Effect.flatMap((ns) => setInternal(e, ns).pipe(Effect.withSpan("SQL.set [effect-app/infra/Store]", {
|
|
190
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name, id: e[idKey] }
|
|
191
|
+
}, { captureStackTrace: false })))),
|
|
192
|
+
batchSet: (items) => resolveNamespace.pipe(Effect.flatMap((ns) => bulkSetInternal(items, ns).pipe(Effect.withSpan("SQL.batchSet [effect-app/infra/Store]", {
|
|
193
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
194
|
+
}, { captureStackTrace: false })))),
|
|
195
|
+
bulkSet: (items) => resolveNamespace.pipe(Effect.flatMap((ns) => bulkSetInternal(items, ns).pipe(Effect.withSpan("SQL.bulkSet [effect-app/infra/Store]", {
|
|
196
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
197
|
+
}, { captureStackTrace: false })))),
|
|
198
|
+
batchRemove: (ids) => {
|
|
199
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
200
|
+
return resolveNamespace.pipe(Effect.flatMap((ns) => exec(`DELETE FROM "${tableName}" WHERE id IN (${placeholders}) AND _namespace = ?`, [...ids, ns])
|
|
201
|
+
.pipe(Effect.asVoid, Effect.withSpan("SQL.batchRemove [effect-app/infra/Store]", {
|
|
202
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
203
|
+
}, { captureStackTrace: false }))));
|
|
204
|
+
},
|
|
205
|
+
queryRaw: (query) => s.all.pipe(Effect.map(query.memory), Effect.withSpan("SQL.queryRaw [effect-app/infra/Store]", {
|
|
206
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
207
|
+
}, { captureStackTrace: false }))
|
|
208
|
+
};
|
|
209
|
+
// Eagerly seed primary namespace on initialization
|
|
210
|
+
yield* seedNamespace("primary");
|
|
211
|
+
return s;
|
|
212
|
+
})
|
|
213
|
+
};
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
function makeSQLiteStorePerNs(withNsSql, { prefix }) {
|
|
217
|
+
return {
|
|
218
|
+
make: (name, idKey, seed, config) => Effect.gen(function* () {
|
|
219
|
+
const tableName = `${prefix}${name}`;
|
|
220
|
+
const defaultValues = config?.defaultValues ?? {};
|
|
221
|
+
const resolveNamespace = !config?.allowNamespace
|
|
222
|
+
? Effect.succeed("primary")
|
|
223
|
+
: storeId.asEffect().pipe(Effect.map((namespace) => {
|
|
224
|
+
if (namespace !== "primary" && !config.allowNamespace(namespace)) {
|
|
225
|
+
throw new Error(`Namespace ${namespace} not allowed!`);
|
|
226
|
+
}
|
|
227
|
+
return namespace;
|
|
228
|
+
}));
|
|
229
|
+
const toRow = (e) => {
|
|
230
|
+
const newE = makeETag(e);
|
|
231
|
+
const id = newE[idKey];
|
|
232
|
+
const { _etag, [idKey]: _id, ...rest } = newE;
|
|
233
|
+
const data = JSON.stringify(rest);
|
|
234
|
+
return { id, _etag: newE._etag, data, item: newE };
|
|
235
|
+
};
|
|
236
|
+
const exec = (ns, query, params) => withNsSql(ns, (sql) => sql.unsafe(query, params).pipe(Effect.orDie));
|
|
237
|
+
const ensureTable = (ns) => withNsSql(ns, (sql) => sql
|
|
238
|
+
.unsafe(`CREATE TABLE IF NOT EXISTS "${tableName}" (id TEXT NOT NULL PRIMARY KEY, _etag TEXT, data JSON NOT NULL)`)
|
|
239
|
+
.pipe(Effect.andThen(sql.unsafe(`CREATE TABLE IF NOT EXISTS "_migrations" (id TEXT NOT NULL, version TEXT NOT NULL, PRIMARY KEY (id, version))`)), Effect.orDie, Effect.asVoid));
|
|
240
|
+
const setInternal = (e, ns) => Effect.gen(function* () {
|
|
241
|
+
const row = toRow(e);
|
|
242
|
+
if (e._etag) {
|
|
243
|
+
yield* exec(ns, `UPDATE "${tableName}" SET _etag = ?, data = ? WHERE id = ? AND _etag = ?`, [row._etag, row.data, row.id, e._etag]);
|
|
244
|
+
const existing = yield* exec(ns, `SELECT _etag FROM "${tableName}" WHERE id = ?`, [row.id]);
|
|
245
|
+
const current = existing[0];
|
|
246
|
+
if (!current || current._etag !== row._etag) {
|
|
247
|
+
if (current) {
|
|
248
|
+
return yield* new OptimisticConcurrencyException({
|
|
249
|
+
type: name,
|
|
250
|
+
id: row.id,
|
|
251
|
+
current: current._etag,
|
|
252
|
+
found: e._etag,
|
|
253
|
+
code: 412
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
return yield* new OptimisticConcurrencyException({
|
|
257
|
+
type: name,
|
|
258
|
+
id: row.id,
|
|
259
|
+
current: "",
|
|
260
|
+
found: e._etag,
|
|
261
|
+
code: 404
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
yield* exec(ns, `INSERT INTO "${tableName}" (id, _etag, data) VALUES (?, ?, ?)`, [row.id, row._etag, row.data]);
|
|
267
|
+
}
|
|
268
|
+
return row.item;
|
|
269
|
+
});
|
|
270
|
+
const bulkSetInternal = (items, ns) => withNsSql(ns, (sql) => sql
|
|
271
|
+
.withTransaction(Effect.forEach(items, (e) => setInternal(e, ns)))
|
|
272
|
+
.pipe(Effect.orDie, Effect.map((_) => _)));
|
|
273
|
+
const ctx = yield* Effect.context();
|
|
274
|
+
const seedCache = new Map();
|
|
275
|
+
const makeSeedEffect = Effect.fnUntraced(function* (ns) {
|
|
276
|
+
yield* ensureTable(ns);
|
|
277
|
+
if (!seed)
|
|
278
|
+
return;
|
|
279
|
+
const existing = yield* exec(ns, `SELECT id FROM "_migrations" WHERE id = ? AND version = ?`, [tableName, tableName]);
|
|
280
|
+
if (existing.length > 0)
|
|
281
|
+
return;
|
|
282
|
+
yield* InfraLogger.logInfo(`Seeding data for ${name} (namespace: ${ns})`);
|
|
283
|
+
const items = yield* seed.pipe(Effect.provide(ctx), Effect.orDie);
|
|
284
|
+
const ne = toNonEmptyArray([...items]);
|
|
285
|
+
if (Option.isSome(ne))
|
|
286
|
+
yield* bulkSetInternal(ne.value, ns);
|
|
287
|
+
yield* exec(ns, `INSERT INTO "_migrations" (id, version) VALUES (?, ?)`, [tableName, tableName]);
|
|
288
|
+
});
|
|
289
|
+
const seedNamespace = (ns) => {
|
|
290
|
+
let cached = seedCache.get(ns);
|
|
291
|
+
if (!cached) {
|
|
292
|
+
cached = Effect.cached(Effect.uninterruptible(makeSeedEffect(ns))).pipe(Effect.runSync);
|
|
293
|
+
seedCache.set(ns, cached);
|
|
294
|
+
}
|
|
295
|
+
return cached;
|
|
296
|
+
};
|
|
297
|
+
const s = {
|
|
298
|
+
seedNamespace: (ns) => seedNamespace(ns),
|
|
299
|
+
all: resolveNamespace.pipe(Effect.flatMap((ns) => exec(ns, `SELECT id, _etag, data FROM "${tableName}"`)
|
|
300
|
+
.pipe(Effect.map((rows) => rows.map((r) => parseRow(r, idKey, defaultValues))), Effect.withSpan("SQLite.all [effect-app/infra/Store]", {
|
|
301
|
+
attributes: {
|
|
302
|
+
"repository.table_name": tableName,
|
|
303
|
+
"repository.model_name": name,
|
|
304
|
+
"repository.namespace": ns
|
|
305
|
+
}
|
|
306
|
+
}, { captureStackTrace: false })))),
|
|
307
|
+
find: (id) => resolveNamespace.pipe(Effect.flatMap((ns) => exec(ns, `SELECT id, _etag, data FROM "${tableName}" WHERE id = ?`, [id])
|
|
308
|
+
.pipe(Effect.map((rows) => {
|
|
309
|
+
const row = rows[0];
|
|
310
|
+
return row
|
|
311
|
+
? Option.some(parseRow(row, idKey, defaultValues))
|
|
312
|
+
: Option.none();
|
|
313
|
+
}), Effect.withSpan("SQLite.find [effect-app/infra/Store]", {
|
|
314
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name, id }
|
|
315
|
+
}, { captureStackTrace: false })))),
|
|
316
|
+
filter: (f) => {
|
|
317
|
+
const filter = f
|
|
318
|
+
.filter;
|
|
319
|
+
return resolveNamespace
|
|
320
|
+
.pipe(Effect
|
|
321
|
+
.flatMap((ns) => Effect
|
|
322
|
+
.sync(() => buildWhereSQLQuery(sqliteDialect, idKey, filter ? [{ t: "where-scope", result: filter, relation: "some" }] : [], tableName, defaultValues, f
|
|
323
|
+
.select, f
|
|
324
|
+
.order, f
|
|
325
|
+
.skip, f
|
|
326
|
+
.limit))
|
|
327
|
+
.pipe(Effect
|
|
328
|
+
.tap((q) => logQuery(q)), Effect.flatMap((q) => exec(ns, q.sql, q.params).pipe(Effect.map((rows) => {
|
|
329
|
+
if (f.select) {
|
|
330
|
+
return rows.map((r) => {
|
|
331
|
+
const selected = parseSelectRow(r, idKey);
|
|
332
|
+
return {
|
|
333
|
+
...Struct.pick(defaultValues, f.select.filter((_) => typeof _ === "string")),
|
|
334
|
+
...selected
|
|
335
|
+
};
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
return rows.map((r) => parseRow(r, idKey, defaultValues));
|
|
339
|
+
}))), Effect.withSpan("SQLite.filter [effect-app/infra/Store]", {
|
|
340
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
341
|
+
}, { captureStackTrace: false }))));
|
|
342
|
+
},
|
|
343
|
+
set: (e) => resolveNamespace.pipe(Effect.flatMap((ns) => setInternal(e, ns).pipe(Effect.withSpan("SQLite.set [effect-app/infra/Store]", {
|
|
344
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name, id: e[idKey] }
|
|
345
|
+
}, { captureStackTrace: false })))),
|
|
346
|
+
batchSet: (items) => resolveNamespace.pipe(Effect.flatMap((ns) => bulkSetInternal(items, ns).pipe(Effect.withSpan("SQLite.batchSet [effect-app/infra/Store]", {
|
|
347
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
348
|
+
}, { captureStackTrace: false })))),
|
|
349
|
+
bulkSet: (items) => resolveNamespace.pipe(Effect.flatMap((ns) => bulkSetInternal(items, ns).pipe(Effect.withSpan("SQLite.bulkSet [effect-app/infra/Store]", {
|
|
350
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
351
|
+
}, { captureStackTrace: false })))),
|
|
352
|
+
batchRemove: (ids) => {
|
|
353
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
354
|
+
return resolveNamespace.pipe(Effect.flatMap((ns) => exec(ns, `DELETE FROM "${tableName}" WHERE id IN (${placeholders})`, [...ids])
|
|
355
|
+
.pipe(Effect.asVoid, Effect.withSpan("SQLite.batchRemove [effect-app/infra/Store]", {
|
|
356
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
357
|
+
}, { captureStackTrace: false }))));
|
|
358
|
+
},
|
|
359
|
+
queryRaw: (query) => s.all.pipe(Effect.map(query.memory), Effect.withSpan("SQLite.queryRaw [effect-app/infra/Store]", {
|
|
360
|
+
attributes: { "repository.table_name": tableName, "repository.model_name": name }
|
|
361
|
+
}, { captureStackTrace: false }))
|
|
362
|
+
};
|
|
363
|
+
yield* seedNamespace("primary");
|
|
364
|
+
return s;
|
|
365
|
+
})
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
export function SQLiteStoreLayer(cfg, options) {
|
|
369
|
+
if (options?.makeSqlClientLayer) {
|
|
370
|
+
return Layer.effectContext(Effect.gen(function* () {
|
|
371
|
+
const layerMap = yield* LayerMap.make((namespace) => options.makeSqlClientLayer(namespace), { idleTimeToLive: "10 minutes" });
|
|
372
|
+
const withNsSql = (ns, f) => SqlClient.SqlClient.use(f).pipe(Effect.provide(layerMap.get(ns)));
|
|
373
|
+
const storeMaker = makeSQLiteStorePerNs(withNsSql, cfg);
|
|
374
|
+
const withTransaction = (effect) => storeId.asEffect().pipe(Effect.flatMap((ns) => withNsSql(ns, (sql) => sql.withTransaction(effect).pipe(Effect.orDie))));
|
|
375
|
+
return StoreMaker.context(storeMaker).pipe(Context.add(WithNsTransaction, withTransaction));
|
|
376
|
+
}));
|
|
377
|
+
}
|
|
378
|
+
return StoreMaker
|
|
379
|
+
.toLayer(makeSQLStoreInt(sqliteDialect, "JSON")(cfg));
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiU1FMLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL1N0b3JlL1NRTC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx1REFBdUQ7QUFFdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLE1BQU0sUUFBUSxDQUFBO0FBQ2pELE9BQU8sRUFBRSxNQUFNLEVBQThCLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFDL0UsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGtCQUFrQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQTtBQUMvQyxPQUFPLEVBQUUsOEJBQThCLEVBQUUsTUFBTSxjQUFjLENBQUE7QUFDN0QsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGNBQWMsQ0FBQTtBQUUxQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQ3JDLE9BQU8sRUFBZ0csVUFBVSxFQUFFLE1BQU0sY0FBYyxDQUFBO0FBQ3ZJLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxRQUFRLEVBQW1CLGFBQWEsRUFBRSxNQUFNLGdCQUFnQixDQUFBO0FBQzdGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxZQUFZLENBQUE7QUFJckMsTUFBTSxPQUFPLGlCQUNYLFNBQVEsT0FBTyxDQUFDLE9BQU8sRUFBMEMsQ0FBQyw4QkFBOEIsQ0FBQztDQUNqRztBQUVGLGdCQUFnQjtBQUNoQixNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsQ0FDdEIsR0FBdUQsRUFDdkQsS0FBa0IsRUFDbEIsYUFBK0IsRUFDQSxFQUFFO0lBQ2pDLE1BQU0sSUFBSSxHQUFHLENBQUMsT0FBTyxHQUFHLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJ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
|
package/dist/Store/index.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Layer } from "effect-app";
|
|
2
|
+
import type { SqlClient } from "effect/unstable/sql";
|
|
2
3
|
import type { StorageConfig } from "./service.js";
|
|
3
|
-
export declare function StoreMakerLayer(cfg: StorageConfig
|
|
4
|
+
export declare function StoreMakerLayer(cfg: StorageConfig, options?: {
|
|
5
|
+
makeSqlClientLayer?: (namespace: string) => Layer.Layer<SqlClient.SqlClient>;
|
|
6
|
+
}): Layer.Layer<import("./service.js").StoreMaker | import("../Model.js").RepositoryRegistry, never, SqlClient.SqlClient>;
|
|
4
7
|
export * from "./service.js";
|
|
5
8
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Store/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,KAAK,EAAY,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/Store/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,KAAK,EAAY,MAAM,YAAY,CAAA;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAMpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAIjD,wBAAgB,eAAe,CAC7B,GAAG,EAAE,aAAa,EAClB,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,CAAA;CAAE,yHA+B3F;AAED,cAAc,cAAc,CAAA"}
|
package/dist/Store/index.js
CHANGED
|
@@ -3,7 +3,11 @@ import { Effect, Layer, Redacted } from "effect-app";
|
|
|
3
3
|
import { CosmosStoreLayer } from "./Cosmos.js";
|
|
4
4
|
import { DiskStoreLayer } from "./Disk.js";
|
|
5
5
|
import { MemoryStoreLive } from "./Memory.js";
|
|
6
|
-
|
|
6
|
+
// import { RedisStoreLayer } from "./Redis.js"
|
|
7
|
+
import { RepositoryRegistryLive } from "../Model.js";
|
|
8
|
+
import { SQLiteStoreLayer } from "./SQL.js";
|
|
9
|
+
import { PgStoreLayer } from "./SQL/Pg.js";
|
|
10
|
+
export function StoreMakerLayer(cfg, options) {
|
|
7
11
|
return Effect
|
|
8
12
|
.sync(() => {
|
|
9
13
|
const storageUrl = Redacted.value(cfg.url);
|
|
@@ -16,6 +20,14 @@ export function StoreMakerLayer(cfg) {
|
|
|
16
20
|
console.log("Using disk store at " + dir);
|
|
17
21
|
return DiskStoreLayer(cfg, dir);
|
|
18
22
|
}
|
|
23
|
+
if (storageUrl.startsWith("sqlite://")) {
|
|
24
|
+
console.log("Using SQLite store");
|
|
25
|
+
return SQLiteStoreLayer(cfg, options);
|
|
26
|
+
}
|
|
27
|
+
if (storageUrl.startsWith("pg://")) {
|
|
28
|
+
console.log("Using PostgreSQL store");
|
|
29
|
+
return PgStoreLayer(cfg);
|
|
30
|
+
}
|
|
19
31
|
// if (storageUrl.startsWith("redis://")) {
|
|
20
32
|
// console.log("Using Redis store")
|
|
21
33
|
// return RedisStoreLayer(cfg)
|
|
@@ -23,7 +35,7 @@ export function StoreMakerLayer(cfg) {
|
|
|
23
35
|
console.log("Using Cosmos DB store");
|
|
24
36
|
return CosmosStoreLayer(cfg);
|
|
25
37
|
})
|
|
26
|
-
.pipe(Layer.unwrap);
|
|
38
|
+
.pipe(Layer.unwrap, Layer.merge(RepositoryRegistryLive));
|
|
27
39
|
}
|
|
28
40
|
export * from "./service.js";
|
|
29
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvU3RvcmUvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLFlBQVksQ0FBQTtBQUVwRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFDOUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQTtBQUMxQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBQzdDLCtDQUErQztBQUMvQyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFFcEQsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sVUFBVSxDQUFBO0FBQzNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxhQUFhLENBQUE7QUFFMUMsTUFBTSxVQUFVLGVBQWUsQ0FDN0IsR0FBa0IsRUFDbEIsT0FBMEY7SUFFMUYsT0FBTyxNQUFNO1NBQ1YsSUFBSSxDQUFDLEdBQUcsRUFBRTtRQUNULE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQzFDLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1lBQ3BDLE9BQU8sQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQTtZQUNwQyxPQUFPLGVBQWUsQ0FBQTtRQUN4QixDQUFDO1FBQ0QsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDckMsTUFBTSxHQUFHLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUE7WUFDN0MsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsR0FBRyxHQUFHLENBQUMsQ0FBQTtZQUN6QyxPQUFPLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUE7UUFDakMsQ0FBQztRQUNELElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ3ZDLE9BQU8sQ0FBQyxHQUFHLENBQUMsb0JBQW9CLENBQUMsQ0FBQTtZQUNqQyxPQUFPLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUN2QyxDQUFDO1FBQ0QsSUFBSSxVQUFVLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDbkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsQ0FBQyxDQUFBO1lBQ3JDLE9BQU8sWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQzFCLENBQUM7UUFDRCwyQ0FBMkM7UUFDM0MscUNBQXFDO1FBQ3JDLGdDQUFnQztRQUNoQyxJQUFJO1FBRUosT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFBO1FBQ3BDLE9BQU8sZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUE7SUFDOUIsQ0FBQyxDQUFDO1NBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLENBQUE7QUFDNUQsQ0FBQztBQUVELGNBQWMsY0FBYyxDQUFBIn0=
|
package/dist/Store/service.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { UniqueKey } from "@azure/cosmos";
|
|
2
|
-
import { Effect, type NonEmptyReadonlyArray, type Option, type Redacted
|
|
2
|
+
import { Context, Effect, type NonEmptyReadonlyArray, type Option, type Redacted } from "effect-app";
|
|
3
3
|
import type { OptimisticConcurrencyException } from "../errors.js";
|
|
4
4
|
import type { FilterResult } from "../Model/filter/filterApi.js";
|
|
5
5
|
import type { FieldValues } from "../Model/filter/types.js";
|
|
@@ -8,8 +8,8 @@ import { type RawQuery } from "../Model/query.js";
|
|
|
8
8
|
export interface StoreConfig<E> {
|
|
9
9
|
partitionValue: (e?: E) => string;
|
|
10
10
|
/**
|
|
11
|
-
* Primarily used for testing, creating namespaces in the database to separate data e.g to run multiple tests in isolation within the same database
|
|
12
|
-
*
|
|
11
|
+
* Primarily used for testing, creating namespaces in the database to separate data e.g to run multiple tests in isolation within the same database.
|
|
12
|
+
* Memory/Disk use separate store instances per namespace. CosmosDB uses namespace-prefixed partition keys. SQL uses a `_namespace` column.
|
|
13
13
|
*/
|
|
14
14
|
allowNamespace?: (namespace: string) => boolean;
|
|
15
15
|
/**
|
|
@@ -75,8 +75,13 @@ export interface Store<IdKey extends keyof Encoded, Encoded extends FieldValues,
|
|
|
75
75
|
bulkSet: (items: NonEmptyReadonlyArray<PM>) => Effect.Effect<NonEmptyReadonlyArray<PM>, OptimisticConcurrencyException>;
|
|
76
76
|
batchRemove: (ids: NonEmptyReadonlyArray<Encoded[IdKey]>, partitionKey?: string) => Effect.Effect<void>;
|
|
77
77
|
queryRaw: <Out>(query: RawQuery<Encoded, Out>) => Effect.Effect<readonly Out[]>;
|
|
78
|
+
/**
|
|
79
|
+
* Explicitly seed a namespace. Primary is seeded eagerly on initialization.
|
|
80
|
+
* Non-primary namespaces must be seeded explicitly before use.
|
|
81
|
+
*/
|
|
82
|
+
seedNamespace: (namespace: string) => Effect.Effect<void>;
|
|
78
83
|
}
|
|
79
|
-
declare const StoreMaker_base:
|
|
84
|
+
declare const StoreMaker_base: Context.OpaqueClass<StoreMaker, "effect-app/StoreMaker", {
|
|
80
85
|
make: <IdKey extends keyof Encoded, Encoded extends FieldValues, R = never, E = never>(name: string, idKey: IdKey, seed?: Effect.Effect<Iterable<Encoded>, E, R>, config?: StoreConfig<Encoded>) => Effect.Effect<Store<IdKey, Encoded>, E, R>;
|
|
81
86
|
}>;
|
|
82
87
|
export declare class StoreMaker extends StoreMaker_base {
|
|
@@ -84,14 +89,20 @@ export declare class StoreMaker extends StoreMaker_base {
|
|
|
84
89
|
export declare const makeContextMap: () => {
|
|
85
90
|
get: (id: string) => string | undefined;
|
|
86
91
|
set: (id: string, eTag: string | undefined) => void;
|
|
92
|
+
getOrCreateStore: <T>(key: symbol, make: () => T) => T;
|
|
93
|
+
getOrCreateStoreEffect: <T, E, R>(key: symbol, make: Effect.Effect<T, E, R>) => Effect.Effect<T, E, R>;
|
|
87
94
|
};
|
|
88
|
-
declare const ContextMap_base:
|
|
95
|
+
declare const ContextMap_base: Context.OpaqueClass<ContextMap, "effect-app/ContextMap", {
|
|
89
96
|
get: (id: string) => string | undefined;
|
|
90
97
|
set: (id: string, eTag: string | undefined) => void;
|
|
98
|
+
getOrCreateStore: <T>(key: symbol, make: () => T) => T;
|
|
99
|
+
getOrCreateStoreEffect: <T, E, R>(key: symbol, make: Effect.Effect<T, E, R>) => Effect.Effect<T, E, R>;
|
|
91
100
|
}> & {
|
|
92
101
|
readonly make: Effect.Effect<{
|
|
93
102
|
get: (id: string) => string | undefined;
|
|
94
103
|
set: (id: string, eTag: string | undefined) => void;
|
|
104
|
+
getOrCreateStore: <T>(key: symbol, make: () => T) => T;
|
|
105
|
+
getOrCreateStoreEffect: <T, E, R>(key: symbol, make: Effect.Effect<T, E, R>) => Effect.Effect<T, E, R>;
|
|
95
106
|
}, never, never>;
|
|
96
107
|
};
|
|
97
108
|
export declare class ContextMap extends ContextMap_base {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/Store/service.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,KAAK,qBAAqB,EAAE,KAAK,MAAM,EAAE,KAAK,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/Store/service.ts"],"names":[],"mappings":"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"}
|
package/dist/Store/service.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
1
|
+
import { Context, Effect } from "effect-app";
|
|
2
|
+
import * as Semaphore from "effect/Semaphore";
|
|
3
|
+
export class StoreMaker extends Context.Opaque()("effect-app/StoreMaker") {
|
|
3
4
|
}
|
|
4
5
|
export const makeContextMap = () => {
|
|
5
6
|
const etags = new Map();
|
|
@@ -59,13 +60,30 @@ export const makeContextMap = () => {
|
|
|
59
60
|
// }
|
|
60
61
|
// }
|
|
61
62
|
// }
|
|
63
|
+
const store = new Map();
|
|
64
|
+
const sem = Semaphore.makeUnsafe(1);
|
|
62
65
|
return {
|
|
63
66
|
get: getEtag,
|
|
64
|
-
set: setEtag
|
|
65
|
-
|
|
67
|
+
set: setEtag,
|
|
68
|
+
getOrCreateStore: (key, make) => {
|
|
69
|
+
let value = store.get(key);
|
|
70
|
+
if (value === undefined) {
|
|
71
|
+
value = make();
|
|
72
|
+
store.set(key, value);
|
|
73
|
+
}
|
|
74
|
+
return value;
|
|
75
|
+
},
|
|
76
|
+
getOrCreateStoreEffect: (key, make) => sem.withPermits(1)(Effect.uninterruptible(Effect.gen(function* () {
|
|
77
|
+
const value = store.get(key);
|
|
78
|
+
if (value !== undefined)
|
|
79
|
+
return value;
|
|
80
|
+
const v = yield* make;
|
|
81
|
+
store.set(key, v);
|
|
82
|
+
return v;
|
|
83
|
+
})))
|
|
66
84
|
};
|
|
67
85
|
};
|
|
68
86
|
const makeMap = Effect.sync(() => makeContextMap());
|
|
69
|
-
export class ContextMap extends
|
|
87
|
+
export class ContextMap extends Context.Opaque()("effect-app/ContextMap", { make: makeMap }) {
|
|
70
88
|
}
|
|
71
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
89
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9TdG9yZS9zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUEwRCxNQUFNLFlBQVksQ0FBQTtBQUNwRyxPQUFPLEtBQUssU0FBUyxNQUFNLGtCQUFrQixDQUFBO0FBOEY3QyxNQUFNLE9BQU8sVUFBVyxTQUFRLE9BQU8sQ0FBQyxNQUFNLEVBTzFDLENBQUMsdUJBQXVCLENBQUM7Q0FDNUI7QUFFRCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsR0FBRyxFQUFFO0lBQ2pDLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFBO0lBQ3ZDLE1BQU0sT0FBTyxHQUFHLENBQUMsRUFBVSxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFBO0lBQzdDLE1BQU0sT0FBTyxHQUFHLENBQUMsRUFBVSxFQUFFLElBQXdCLEVBQUUsRUFBRTtRQUN2RCxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN2QixLQUFLLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ2xCLENBQUM7YUFBTSxDQUFDO1lBQ04sS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUE7UUFDckIsQ0FBQztJQUNILENBQUMsQ0FBQTtJQUVELCtCQUErQjtJQUMvQiwyQkFBMkI7SUFDM0IsZ0RBQWdEO0lBQ2hELE1BQU07SUFFTiwrQkFBK0I7SUFDL0IsMkJBQTJCO0lBQzNCLHNDQUFzQztJQUN0QyxNQUFNO0lBRU4sa0NBQWtDO0lBQ2xDLHdCQUF3QjtJQUN4QixvQ0FBb0M7SUFDcEMsU0FBUztJQUNULDJCQUEyQjtJQUMzQixjQUFjO0lBQ2QsSUFBSTtJQUVKLGlDQUFpQztJQUNqQyxvRkFBb0Y7SUFDcEYsb0lBQW9JO0lBQ3BJLGdCQUFnQjtJQUNoQixhQUFhO0lBQ2IsNEdBQTRHO0lBQzVHLHNDQUFzQztJQUN0QyxrRUFBa0U7SUFDbEUsdURBQXVEO0lBQ3ZELHNCQUFzQjtJQUN0QixzQkFBc0I7SUFDdEIsU0FBUztJQUNULHFDQUFxQztJQUNyQyx5Q0FBeUM7SUFDekMsaUJBQWlCO0lBQ2pCLDZCQUE2QjtJQUM3QixtQkFBbUI7SUFDbkIsK0NBQStDO0lBQy9DLHFCQUFxQjtJQUNyQixtQkFBbUI7SUFDbkIsMkNBQTJDO0lBQzNDLHlCQUF5QjtJQUN6QixzQkFBc0I7SUFDdEIsWUFBWTtJQUNaLGlCQUFpQjtJQUNqQix5Q0FBeUM7SUFDekMscURBQXFEO0lBQ3JELG9CQUFvQjtJQUNwQixVQUFVO0lBQ1YsUUFBUTtJQUNSLE1BQU07SUFDTixJQUFJO0lBRUosTUFBTSxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUE7SUFDeEMsTUFBTSxHQUFHLEdBQUcsU0FBUyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUVuQyxPQUFPO1FBQ0wsR0FBRyxFQUFFLE9BQU87UUFDWixHQUFHLEVBQUUsT0FBTztRQUNaLGdCQUFnQixFQUFFLENBQUksR0FBVyxFQUFFLElBQWEsRUFBSyxFQUFFO1lBQ3JELElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFrQixDQUFBO1lBQzNDLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO2dCQUN4QixLQUFLLEdBQUcsSUFBSSxFQUFFLENBQUE7Z0JBQ2QsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUE7WUFDdkIsQ0FBQztZQUNELE9BQU8sS0FBSyxDQUFBO1FBQ2QsQ0FBQztRQUNELHNCQUFzQixFQUFFLENBQVUsR0FBVyxFQUFFLElBQTRCLEVBQTBCLEVBQUUsQ0FDckcsR0FBRyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDO1lBQzVELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFrQixDQUFBO1lBQzdDLElBQUksS0FBSyxLQUFLLFNBQVM7Z0JBQUUsT0FBTyxLQUFLLENBQUE7WUFDckMsTUFBTSxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFBO1lBQ3JCLEtBQUssQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFBO1lBQ2pCLE9BQU8sQ0FBQyxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUNQLENBQUE7QUFDSCxDQUFDLENBQUE7QUFFRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUE7QUFFbkQsTUFBTSxPQUFPLFVBQVcsU0FBUSxPQUFPLENBQUMsTUFBTSxFQUFjLENBQUMsdUJBQXVCLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUM7Q0FDdkcifQ==
|