@fougere/app 0.5.0-alpha.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/boot.d.ts +3 -14
- package/dist/boot.d.ts.map +1 -1
- package/dist/boot.js +10 -148
- package/dist/boot.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/package.json +11 -10
- package/src/boot.ts +13 -136
- package/src/index.ts +3 -1
package/dist/boot.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { App, CreateAppOptions,
|
|
1
|
+
import type { App, CreateAppOptions, Storage, FougereConfig, Transport } from '@fougere/core';
|
|
2
2
|
import { type SchemaView } from '@fougere/schema';
|
|
3
3
|
export interface FougereServerConfig {
|
|
4
4
|
/** Storage handle. Forwarded to the auth provider via AuthContext.db. */
|
|
5
5
|
db?: unknown;
|
|
6
|
-
/** Per-entity
|
|
7
|
-
|
|
6
|
+
/** Per-entity storage factory. */
|
|
7
|
+
storageFactory?: (entity: SchemaView, name: string) => Storage;
|
|
8
8
|
/**
|
|
9
9
|
* What this app takes on beyond its fronds, each stating what it does and what it undoes.
|
|
10
10
|
*
|
|
@@ -102,15 +102,4 @@ export declare function useFougereApp(): Promise<App>;
|
|
|
102
102
|
* because a caller who cannot wait must choose that on purpose.
|
|
103
103
|
*/
|
|
104
104
|
export declare function reloadFougere(timeoutMs?: number): Promise<App>;
|
|
105
|
-
/**
|
|
106
|
-
* The store an app with no `db` runs on.
|
|
107
|
-
*
|
|
108
|
-
* It used to ignore both its arguments — `(_entity, _name)` — so it forced the field
|
|
109
|
-
* name `id`, minted a uuid whatever the entity declared, and realized none of the
|
|
110
|
-
* lifecycle rules: `created()` stamped nothing, a declared default stayed absent. The
|
|
111
|
-
* same page therefore behaved one way here and another way on SQLite.
|
|
112
|
-
*
|
|
113
|
-
* It reads the axes now, through the one realization every storage shares.
|
|
114
|
-
*/
|
|
115
|
-
export declare function createMemoryOrm(entity: SchemaView, name: string): EntityOrm;
|
|
116
105
|
//# sourceMappingURL=boot.d.ts.map
|
package/dist/boot.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../src/boot.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"boot.d.ts","sourceRoot":"","sources":["../src/boot.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC9F,OAAO,EAA4B,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAI5E,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,kCAAkC;IAClC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IAC/D;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC5C;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;;;;;;;OAWG;IACH,IAAI,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAChC;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACpC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAChC;;;;;;;;;;;OAWG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;CAC9C;AASD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,mBAAmB,QAG3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,QAGjE;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,CAK5C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAWpE"}
|
package/dist/boot.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { Role } from '@fougere/schema';
|
|
2
|
-
import { Lifecycle } from '@fougere/schema';
|
|
3
1
|
/**
|
|
4
2
|
* Fougere server bootstrap — single entry point for an app's lifecycle,
|
|
5
3
|
* whatever hosts it.
|
|
@@ -12,16 +10,16 @@ import { Lifecycle } from '@fougere/schema';
|
|
|
12
10
|
*
|
|
13
11
|
* Default path (zero-config): fougere.config.ts declares `db: 'sqlite'` and
|
|
14
12
|
* everything else; this module auto-resolves the storage handle, builds an
|
|
15
|
-
*
|
|
13
|
+
* storageFactory, runs auto-DDL from the entities, and boots the app.
|
|
16
14
|
*
|
|
17
|
-
* Escape hatch: `configureFougere({ db,
|
|
15
|
+
* Escape hatch: `configureFougere({ db, storageFactory })` can be called from the
|
|
18
16
|
* host's own startup (a Nitro plugin, a Next instrumentation hook) if the user
|
|
19
17
|
* wants a custom data layer — alternative driver, managed migrations, etc.
|
|
20
18
|
*/
|
|
21
19
|
import { createApp, identityFromEnv, Logger, migrating, seeding } from '@fougere/core';
|
|
22
20
|
import { scanProject, loadCascadedConfig, setModuleLoader, frondAliases, resolveConventions } from '@fougere/core/node';
|
|
23
21
|
import { createContainer } from '@fougere/container';
|
|
24
|
-
import {
|
|
22
|
+
import { createMemoryStorage } from '@fougere/adapter-memory';
|
|
25
23
|
// ── State ────────────────────────────────────────
|
|
26
24
|
let _config = {};
|
|
27
25
|
let _appPromise = null;
|
|
@@ -125,7 +123,7 @@ async function boot() {
|
|
|
125
123
|
// custom one via configureFougere. The resolution itself lives in @fougere/defaults
|
|
126
124
|
// — this host must not know which storage package backs `db:`.
|
|
127
125
|
let db = _config.db;
|
|
128
|
-
let
|
|
126
|
+
let storageFactory = _config.storageFactory;
|
|
129
127
|
// The storage's two halves, kept together: its ascent is an extension, its connection
|
|
130
128
|
// is not — it is opened here, before the container, so it closes after the container.
|
|
131
129
|
let storageMigrate;
|
|
@@ -134,21 +132,21 @@ async function boot() {
|
|
|
134
132
|
// resolution, because a frame's realization is decided by `sources:` and nothing else.
|
|
135
133
|
let sourceOf;
|
|
136
134
|
let transacted;
|
|
137
|
-
if (!
|
|
135
|
+
if (!storageFactory) {
|
|
138
136
|
const { resolveStorage } = await import('@fougere/defaults');
|
|
139
137
|
const storage = resolveStorage(fileConfig.db, fileConfig.sources);
|
|
140
|
-
if (storage.
|
|
138
|
+
if (storage.storageFactory) {
|
|
141
139
|
log.debug('auto-resolving storage from config.db');
|
|
142
140
|
db = storage.db;
|
|
143
|
-
|
|
141
|
+
storageFactory = storage.storageFactory;
|
|
144
142
|
sourceOf = storage.sourceOf;
|
|
145
143
|
transacted = storage.transacted;
|
|
146
144
|
storageMigrate = storage.migrate;
|
|
147
145
|
closeStorage = storage.close;
|
|
148
146
|
}
|
|
149
147
|
else {
|
|
150
|
-
log.debug('no db declared — falling back to in-memory
|
|
151
|
-
|
|
148
|
+
log.debug('no db declared — falling back to in-memory storage');
|
|
149
|
+
storageFactory = createMemoryStorage;
|
|
152
150
|
}
|
|
153
151
|
}
|
|
154
152
|
// Layer-2 wiring: `remotes: { catalog: 'http://...' }` in fougere.config.ts
|
|
@@ -180,7 +178,7 @@ async function boot() {
|
|
|
180
178
|
? { scan: await scanProject(root, undefined, conventions) }
|
|
181
179
|
: {}),
|
|
182
180
|
createContainer,
|
|
183
|
-
|
|
181
|
+
storageFactory,
|
|
184
182
|
sourceOf,
|
|
185
183
|
transacted,
|
|
186
184
|
db,
|
|
@@ -211,140 +209,4 @@ async function boot() {
|
|
|
211
209
|
log.info(`ready in ${ms}ms — ${app.fronds.length} frond(s)${app.auth ? ` + auth (${app.auth.basePath})` : ''}`);
|
|
212
210
|
return app;
|
|
213
211
|
}
|
|
214
|
-
// ── Fallback ORM ─────────────────────────────────
|
|
215
|
-
/**
|
|
216
|
-
* The store an app with no `db` runs on.
|
|
217
|
-
*
|
|
218
|
-
* It used to ignore both its arguments — `(_entity, _name)` — so it forced the field
|
|
219
|
-
* name `id`, minted a uuid whatever the entity declared, and realized none of the
|
|
220
|
-
* lifecycle rules: `created()` stamped nothing, a declared default stayed absent. The
|
|
221
|
-
* same page therefore behaved one way here and another way on SQLite.
|
|
222
|
-
*
|
|
223
|
-
* It reads the axes now, through the one realization every storage shares.
|
|
224
|
-
*/
|
|
225
|
-
export function createMemoryOrm(entity, name) {
|
|
226
|
-
const fields = entity.getFields();
|
|
227
|
-
const pk = Object.entries(fields).find(([, field]) => Role.of(field).isPrimary)?.[0] ?? 'id';
|
|
228
|
-
const store = new Map();
|
|
229
|
-
// `EntityOrm.findById(id: string)` — but a key can hold a number, and a Map keyed on
|
|
230
|
-
// `1` does not answer `'1'`. SQL never had the question; here the divergence was
|
|
231
|
-
// silent and only on this storage.
|
|
232
|
-
const keyOf = (value) => String(value);
|
|
233
|
-
// Same contract as SQL: a criterion may name a SET, and an empty set matches nothing.
|
|
234
|
-
const matches = (row, criteria) => Object.entries(criteria).every(([key, value]) => Array.isArray(value)
|
|
235
|
-
? value.some((v) => Object.is(row[key], v))
|
|
236
|
-
: Object.is(row[key], value));
|
|
237
|
-
return {
|
|
238
|
-
client: store,
|
|
239
|
-
async list(options) {
|
|
240
|
-
let items = [...store.values()];
|
|
241
|
-
if (options?.where)
|
|
242
|
-
items = items.filter((row) => matches(row, options.where));
|
|
243
|
-
// Held before the page is cut, and after the filter: `total` answers "how many
|
|
244
|
-
// match", which is what a paginator divides. Reading `store.size` at the end
|
|
245
|
-
// answered a different question — every row the store holds, including the ones
|
|
246
|
-
// the filter exists to keep out of this caller's sight.
|
|
247
|
-
const matching = items.length;
|
|
248
|
-
const limit = options?.limit;
|
|
249
|
-
const offset = options?.page && limit ? (options.page - 1) * limit : options?.offset ?? 0;
|
|
250
|
-
if (offset > 0)
|
|
251
|
-
items = items.slice(offset);
|
|
252
|
-
const hasMore = limit ? items.length > limit : false;
|
|
253
|
-
if (limit)
|
|
254
|
-
items = items.slice(0, limit);
|
|
255
|
-
const result = items;
|
|
256
|
-
result.hasMore = hasMore;
|
|
257
|
-
result.endCursor = items.length > 0 ? String(items[items.length - 1][pk] ?? '') : undefined;
|
|
258
|
-
if (options?.count)
|
|
259
|
-
result.total = matching;
|
|
260
|
-
return result;
|
|
261
|
-
},
|
|
262
|
-
async findById(id) { return store.get(keyOf(id)); },
|
|
263
|
-
async findBy(criteria) {
|
|
264
|
-
return [...store.values()].find((row) => matches(row, criteria));
|
|
265
|
-
},
|
|
266
|
-
async findAllBy(criteria) {
|
|
267
|
-
return [...store.values()].filter((row) => matches(row, criteria));
|
|
268
|
-
},
|
|
269
|
-
// Same contract as SQL: a map keyed by the primary key, a miss being an absent key.
|
|
270
|
-
async findByKeys(ids) {
|
|
271
|
-
const found = new Map();
|
|
272
|
-
for (const id of ids) {
|
|
273
|
-
const row = store.get(keyOf(id));
|
|
274
|
-
if (row)
|
|
275
|
-
found.set(String(id), row);
|
|
276
|
-
}
|
|
277
|
-
return found;
|
|
278
|
-
},
|
|
279
|
-
// The dual, same contract as SQL: grouped by the value read off the ROW.
|
|
280
|
-
async findAllByKeys(field, keys) {
|
|
281
|
-
const grouped = new Map();
|
|
282
|
-
if (keys.length === 0)
|
|
283
|
-
return grouped;
|
|
284
|
-
const wanted = new Set(keys.map(String));
|
|
285
|
-
for (const row of store.values()) {
|
|
286
|
-
const key = String(row[field]);
|
|
287
|
-
if (!wanted.has(key))
|
|
288
|
-
continue;
|
|
289
|
-
const held = grouped.get(key);
|
|
290
|
-
if (held)
|
|
291
|
-
held.push(row);
|
|
292
|
-
else
|
|
293
|
-
grouped.set(key, [row]);
|
|
294
|
-
}
|
|
295
|
-
return grouped;
|
|
296
|
-
},
|
|
297
|
-
// Same contract as SQL: the key and the creation stamps survive an overwrite.
|
|
298
|
-
async upsert(input) {
|
|
299
|
-
const record = applyCreate(fields, applyUpdate(fields, input));
|
|
300
|
-
const id = record[pk];
|
|
301
|
-
if (id === undefined)
|
|
302
|
-
throw new Error(`${name}.upsert(): no \`${pk}\` — an upsert needs the key it writes at.`);
|
|
303
|
-
const held = store.get(keyOf(id));
|
|
304
|
-
if (held) {
|
|
305
|
-
for (const [key, field] of Object.entries(fields)) {
|
|
306
|
-
if (key === pk || Lifecycle.of(field).stampedOnce)
|
|
307
|
-
record[key] = held[key];
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
store.set(keyOf(id), record);
|
|
311
|
-
return record;
|
|
312
|
-
},
|
|
313
|
-
async upsertAll(inputs) {
|
|
314
|
-
for (const input of inputs)
|
|
315
|
-
await this.upsert(input);
|
|
316
|
-
return inputs.length;
|
|
317
|
-
},
|
|
318
|
-
async create(input) {
|
|
319
|
-
const record = applyCreate(fields, input);
|
|
320
|
-
const id = record[pk];
|
|
321
|
-
// `primary(text())` declares no generator, so nothing fills the hole and the
|
|
322
|
-
// caller has to. Keying on `undefined` would let the second create overwrite the
|
|
323
|
-
// first, in silence — the old version hid this by inventing an `id` field the
|
|
324
|
-
// entity never declared.
|
|
325
|
-
if (id === undefined) {
|
|
326
|
-
throw new Error(`${name}.create: '${pk}' is the primary key and nothing supplied it — this entity declares no generator for it.`);
|
|
327
|
-
}
|
|
328
|
-
// A create is not an upsert. `Map.set` overwrites, so a second create under the
|
|
329
|
-
// same key answered "created" while destroying the previous row — SQL answers a
|
|
330
|
-
// constraint violation, and a store that loses data silently is worse than one
|
|
331
|
-
// that fails.
|
|
332
|
-
if (store.has(keyOf(id))) {
|
|
333
|
-
throw new Error(`${name}.create: '${pk}' ${JSON.stringify(id)} already exists.`);
|
|
334
|
-
}
|
|
335
|
-
store.set(keyOf(id), record);
|
|
336
|
-
return record;
|
|
337
|
-
},
|
|
338
|
-
async update(id, input) {
|
|
339
|
-
const existing = store.get(keyOf(id));
|
|
340
|
-
if (!existing)
|
|
341
|
-
throw new Error(`Not found: ${id}`);
|
|
342
|
-
const updated = { ...existing, ...applyUpdate(fields, input), [pk]: existing[pk] };
|
|
343
|
-
store.set(keyOf(id), updated);
|
|
344
|
-
return updated;
|
|
345
|
-
},
|
|
346
|
-
async delete(id) { return store.delete(keyOf(id)); },
|
|
347
|
-
output(_schema) { return this; },
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
212
|
//# sourceMappingURL=boot.js.map
|
package/dist/boot.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boot.js","sourceRoot":"","sources":["../src/boot.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"boot.js","sourceRoot":"","sources":["../src/boot.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* The root entry pulls in the boot, which reads the filesystem — client code wants
|
|
10
10
|
* `@fougere/app/client`.
|
|
11
11
|
*/
|
|
12
|
-
export { configureFougere, extendFougere, useFougereApp, reloadFougere,
|
|
12
|
+
export { configureFougere, extendFougere, useFougereApp, reloadFougere, type FougereServerConfig, } from './boot.js';
|
|
13
13
|
export { useFougereAuth } from './auth.js';
|
|
14
14
|
export { tableOf, matchRoute, type Matchable, type RouteMatch, } from './rest.js';
|
|
15
15
|
export { serveRest, shapeRest, serveRpc, surfaceOf, rpcParseError, invokeOn, type DoorRequest, type Outcome, } from './serve.js';
|
|
@@ -17,4 +17,5 @@ export { formFieldsOf, tableColumnsOf, payloadOf, errorsByField, type FormEntity
|
|
|
17
17
|
export { sessionViewOf, type SessionView } from './session.js';
|
|
18
18
|
export { stateFor } from './state.js';
|
|
19
19
|
export { serveGraphQL, type GraphQLRequest } from './graphql.js';
|
|
20
|
+
export { createMemoryStorage } from '@fougere/adapter-memory';
|
|
20
21
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,aAAa,EACb,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,aAAa,EACb,KAAK,mBAAmB,GACzB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EACL,OAAO,EACP,UAAU,EACV,KAAK,SAAS,EACd,KAAK,UAAU,GAChB,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,aAAa,EACb,QAAQ,EACR,KAAK,WAAW,EAChB,KAAK,OAAO,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,SAAS,EACT,aAAa,EACb,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,WAAW,GACjB,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAGjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* The root entry pulls in the boot, which reads the filesystem — client code wants
|
|
10
10
|
* `@fougere/app/client`.
|
|
11
11
|
*/
|
|
12
|
-
export { configureFougere, extendFougere, useFougereApp, reloadFougere,
|
|
12
|
+
export { configureFougere, extendFougere, useFougereApp, reloadFougere, } from './boot.js';
|
|
13
13
|
export { useFougereAuth } from './auth.js';
|
|
14
14
|
export { tableOf, matchRoute, } from './rest.js';
|
|
15
15
|
export { serveRest, shapeRest, serveRpc, surfaceOf, rpcParseError, invokeOn, } from './serve.js';
|
|
@@ -17,4 +17,6 @@ export { formFieldsOf, tableColumnsOf, payloadOf, errorsByField, } from './form.
|
|
|
17
17
|
export { sessionViewOf } from './session.js';
|
|
18
18
|
export { stateFor } from './state.js';
|
|
19
19
|
export { serveGraphQL } from './graphql.js';
|
|
20
|
+
// Re-exported where every host already looks for it; it lives in its own adapter now.
|
|
21
|
+
export { createMemoryStorage } from '@fougere/adapter-memory';
|
|
20
22
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,aAAa,EACb,aAAa,GAEd,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EACL,OAAO,EACP,UAAU,GAGX,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,SAAS,EACT,SAAS,EACT,QAAQ,EACR,SAAS,EACT,aAAa,EACb,QAAQ,GAGT,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,SAAS,EACT,aAAa,GAId,MAAM,WAAW,CAAC;AAEnB,OAAO,EAAE,aAAa,EAAoB,MAAM,cAAc,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,YAAY,EAAuB,MAAM,cAAc,CAAC;AAEjE,sFAAsF;AACtF,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fougere/app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "The host-independent half of a Fougere app: boot, call envelope, REST table, form contract.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fougere",
|
|
@@ -42,23 +42,24 @@
|
|
|
42
42
|
],
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"jiti": "^2.6.1",
|
|
45
|
-
"@fougere/core": "0.
|
|
46
|
-
"@fougere/schema": "0.
|
|
47
|
-
"@fougere/
|
|
48
|
-
"@fougere/
|
|
49
|
-
"@fougere/
|
|
50
|
-
"@fougere/http": "0.
|
|
51
|
-
"@fougere/
|
|
45
|
+
"@fougere/core": "0.6.0-alpha.0",
|
|
46
|
+
"@fougere/schema": "0.6.0-alpha.0",
|
|
47
|
+
"@fougere/adapter-rest": "0.6.0-alpha.0",
|
|
48
|
+
"@fougere/defaults": "0.6.0-alpha.0",
|
|
49
|
+
"@fougere/http": "0.6.0-alpha.0",
|
|
50
|
+
"@fougere/transport-http": "0.6.0-alpha.0",
|
|
51
|
+
"@fougere/container": "0.6.0-alpha.0",
|
|
52
|
+
"@fougere/adapter-memory": "0.6.0-alpha.0"
|
|
52
53
|
},
|
|
53
54
|
"devDependencies": {
|
|
54
55
|
"vitest": "^4.1.0",
|
|
55
|
-
"@fougere/adapter-graphql": "0.
|
|
56
|
+
"@fougere/adapter-graphql": "0.6.0-alpha.0"
|
|
56
57
|
},
|
|
57
58
|
"publishConfig": {
|
|
58
59
|
"access": "public"
|
|
59
60
|
},
|
|
60
61
|
"peerDependencies": {
|
|
61
|
-
"@fougere/adapter-graphql": "0.
|
|
62
|
+
"@fougere/adapter-graphql": "0.6.0-alpha.0"
|
|
62
63
|
},
|
|
63
64
|
"peerDependenciesMeta": {
|
|
64
65
|
"@fougere/adapter-graphql": {
|
package/src/boot.ts
CHANGED
|
@@ -12,9 +12,9 @@ import { Lifecycle } from '@fougere/schema';
|
|
|
12
12
|
*
|
|
13
13
|
* Default path (zero-config): fougere.config.ts declares `db: 'sqlite'` and
|
|
14
14
|
* everything else; this module auto-resolves the storage handle, builds an
|
|
15
|
-
*
|
|
15
|
+
* storageFactory, runs auto-DDL from the entities, and boots the app.
|
|
16
16
|
*
|
|
17
|
-
* Escape hatch: `configureFougere({ db,
|
|
17
|
+
* Escape hatch: `configureFougere({ db, storageFactory })` can be called from the
|
|
18
18
|
* host's own startup (a Nitro plugin, a Next instrumentation hook) if the user
|
|
19
19
|
* wants a custom data layer — alternative driver, managed migrations, etc.
|
|
20
20
|
*/
|
|
@@ -22,7 +22,8 @@ import { createApp, identityFromEnv, Logger, migrating, seeding } from '@fougere
|
|
|
22
22
|
import { scanProject, loadCascadedConfig, setModuleLoader, frondAliases, resolveConventions } from '@fougere/core/node';
|
|
23
23
|
import type { Extension } from '@fougere/core';
|
|
24
24
|
import { createContainer } from '@fougere/container';
|
|
25
|
-
import
|
|
25
|
+
import { createMemoryStorage } from '@fougere/adapter-memory';
|
|
26
|
+
import type { App, CreateAppOptions, Storage, FougereConfig, Transport } from '@fougere/core';
|
|
26
27
|
import { applyCreate, applyUpdate, type SchemaView } from '@fougere/schema';
|
|
27
28
|
|
|
28
29
|
// ── Public types ─────────────────────────────────
|
|
@@ -30,8 +31,8 @@ import { applyCreate, applyUpdate, type SchemaView } from '@fougere/schema';
|
|
|
30
31
|
export interface FougereServerConfig {
|
|
31
32
|
/** Storage handle. Forwarded to the auth provider via AuthContext.db. */
|
|
32
33
|
db?: unknown;
|
|
33
|
-
/** Per-entity
|
|
34
|
-
|
|
34
|
+
/** Per-entity storage factory. */
|
|
35
|
+
storageFactory?: (entity: SchemaView, name: string) => Storage;
|
|
35
36
|
/**
|
|
36
37
|
* What this app takes on beyond its fronds, each stating what it does and what it undoes.
|
|
37
38
|
*
|
|
@@ -209,7 +210,7 @@ async function boot(): Promise<App> {
|
|
|
209
210
|
// custom one via configureFougere. The resolution itself lives in @fougere/defaults
|
|
210
211
|
// — this host must not know which storage package backs `db:`.
|
|
211
212
|
let db = _config.db;
|
|
212
|
-
let
|
|
213
|
+
let storageFactory = _config.storageFactory;
|
|
213
214
|
// The storage's two halves, kept together: its ascent is an extension, its connection
|
|
214
215
|
// is not — it is opened here, before the container, so it closes after the container.
|
|
215
216
|
let storageMigrate: Extension['up'] | undefined;
|
|
@@ -218,20 +219,20 @@ async function boot(): Promise<App> {
|
|
|
218
219
|
// resolution, because a frame's realization is decided by `sources:` and nothing else.
|
|
219
220
|
let sourceOf: ((entityName: string) => string) | undefined;
|
|
220
221
|
let transacted: CreateAppOptions['transacted'];
|
|
221
|
-
if (!
|
|
222
|
+
if (!storageFactory) {
|
|
222
223
|
const { resolveStorage } = await import('@fougere/defaults');
|
|
223
224
|
const storage = resolveStorage(fileConfig.db as never, (fileConfig as { sources?: unknown }).sources as never);
|
|
224
|
-
if (storage.
|
|
225
|
+
if (storage.storageFactory) {
|
|
225
226
|
log.debug('auto-resolving storage from config.db');
|
|
226
227
|
db = storage.db;
|
|
227
|
-
|
|
228
|
+
storageFactory = storage.storageFactory;
|
|
228
229
|
sourceOf = storage.sourceOf;
|
|
229
230
|
transacted = storage.transacted as never;
|
|
230
231
|
storageMigrate = storage.migrate;
|
|
231
232
|
closeStorage = storage.close;
|
|
232
233
|
} else {
|
|
233
|
-
log.debug('no db declared — falling back to in-memory
|
|
234
|
-
|
|
234
|
+
log.debug('no db declared — falling back to in-memory storage');
|
|
235
|
+
storageFactory = createMemoryStorage;
|
|
235
236
|
}
|
|
236
237
|
}
|
|
237
238
|
|
|
@@ -265,7 +266,7 @@ async function boot(): Promise<App> {
|
|
|
265
266
|
? { scan: await scanProject(root, undefined, conventions) }
|
|
266
267
|
: {}),
|
|
267
268
|
createContainer,
|
|
268
|
-
|
|
269
|
+
storageFactory,
|
|
269
270
|
sourceOf,
|
|
270
271
|
transacted,
|
|
271
272
|
db,
|
|
@@ -300,127 +301,3 @@ async function boot(): Promise<App> {
|
|
|
300
301
|
return app;
|
|
301
302
|
}
|
|
302
303
|
|
|
303
|
-
// ── Fallback ORM ─────────────────────────────────
|
|
304
|
-
|
|
305
|
-
/**
|
|
306
|
-
* The store an app with no `db` runs on.
|
|
307
|
-
*
|
|
308
|
-
* It used to ignore both its arguments — `(_entity, _name)` — so it forced the field
|
|
309
|
-
* name `id`, minted a uuid whatever the entity declared, and realized none of the
|
|
310
|
-
* lifecycle rules: `created()` stamped nothing, a declared default stayed absent. The
|
|
311
|
-
* same page therefore behaved one way here and another way on SQLite.
|
|
312
|
-
*
|
|
313
|
-
* It reads the axes now, through the one realization every storage shares.
|
|
314
|
-
*/
|
|
315
|
-
export function createMemoryOrm(entity: SchemaView, name: string): EntityOrm {
|
|
316
|
-
const fields = entity.getFields();
|
|
317
|
-
const pk = Object.entries(fields).find(([, field]) => Role.of(field).isPrimary)?.[0] ?? 'id';
|
|
318
|
-
const store = new Map<string, Record<string, unknown>>();
|
|
319
|
-
// `EntityOrm.findById(id: string)` — but a key can hold a number, and a Map keyed on
|
|
320
|
-
// `1` does not answer `'1'`. SQL never had the question; here the divergence was
|
|
321
|
-
// silent and only on this storage.
|
|
322
|
-
const keyOf = (value: unknown) => String(value);
|
|
323
|
-
// Same contract as SQL: a criterion may name a SET, and an empty set matches nothing.
|
|
324
|
-
const matches = (row: Record<string, unknown>, criteria: Record<string, unknown>) =>
|
|
325
|
-
Object.entries(criteria).every(([key, value]) => Array.isArray(value)
|
|
326
|
-
? value.some((v) => Object.is(row[key], v))
|
|
327
|
-
: Object.is(row[key], value));
|
|
328
|
-
return {
|
|
329
|
-
client: store,
|
|
330
|
-
async list(options?: any) {
|
|
331
|
-
let items = [...store.values()];
|
|
332
|
-
if (options?.where) items = items.filter((row) => matches(row, options.where));
|
|
333
|
-
// Held before the page is cut, and after the filter: `total` answers "how many
|
|
334
|
-
// match", which is what a paginator divides. Reading `store.size` at the end
|
|
335
|
-
// answered a different question — every row the store holds, including the ones
|
|
336
|
-
// the filter exists to keep out of this caller's sight.
|
|
337
|
-
const matching = items.length;
|
|
338
|
-
const limit = options?.limit;
|
|
339
|
-
const offset = options?.page && limit ? (options.page - 1) * limit : options?.offset ?? 0;
|
|
340
|
-
if (offset > 0) items = items.slice(offset);
|
|
341
|
-
const hasMore = limit ? items.length > limit : false;
|
|
342
|
-
if (limit) items = items.slice(0, limit);
|
|
343
|
-
const result = items as any;
|
|
344
|
-
result.hasMore = hasMore;
|
|
345
|
-
result.endCursor = items.length > 0 ? String((items[items.length - 1] as any)[pk] ?? '') : undefined;
|
|
346
|
-
if (options?.count) result.total = matching;
|
|
347
|
-
return result;
|
|
348
|
-
},
|
|
349
|
-
async findById(id: string) { return store.get(keyOf(id)); },
|
|
350
|
-
async findBy(criteria: Record<string, unknown>) {
|
|
351
|
-
return [...store.values()].find((row) => matches(row, criteria));
|
|
352
|
-
},
|
|
353
|
-
async findAllBy(criteria: Record<string, unknown>) {
|
|
354
|
-
return [...store.values()].filter((row) => matches(row, criteria));
|
|
355
|
-
},
|
|
356
|
-
// Same contract as SQL: a map keyed by the primary key, a miss being an absent key.
|
|
357
|
-
async findByKeys(ids: readonly string[]) {
|
|
358
|
-
const found = new Map<string, Record<string, unknown>>();
|
|
359
|
-
for (const id of ids) {
|
|
360
|
-
const row = store.get(keyOf(id));
|
|
361
|
-
if (row) found.set(String(id), row);
|
|
362
|
-
}
|
|
363
|
-
return found;
|
|
364
|
-
},
|
|
365
|
-
// The dual, same contract as SQL: grouped by the value read off the ROW.
|
|
366
|
-
async findAllByKeys(field: string, keys: readonly string[]) {
|
|
367
|
-
const grouped = new Map<string, Record<string, unknown>[]>();
|
|
368
|
-
if (keys.length === 0) return grouped;
|
|
369
|
-
const wanted = new Set(keys.map(String));
|
|
370
|
-
for (const row of store.values()) {
|
|
371
|
-
const key = String(row[field]);
|
|
372
|
-
if (!wanted.has(key)) continue;
|
|
373
|
-
const held = grouped.get(key);
|
|
374
|
-
if (held) held.push(row); else grouped.set(key, [row]);
|
|
375
|
-
}
|
|
376
|
-
return grouped;
|
|
377
|
-
},
|
|
378
|
-
// Same contract as SQL: the key and the creation stamps survive an overwrite.
|
|
379
|
-
async upsert(input: Partial<Record<string, unknown>>) {
|
|
380
|
-
const record = applyCreate(fields, applyUpdate(fields, input));
|
|
381
|
-
const id = record[pk] as string | undefined;
|
|
382
|
-
if (id === undefined) throw new Error(`${name}.upsert(): no \`${pk}\` — an upsert needs the key it writes at.`);
|
|
383
|
-
const held = store.get(keyOf(id));
|
|
384
|
-
if (held) {
|
|
385
|
-
for (const [key, field] of Object.entries(fields)) {
|
|
386
|
-
if (key === pk || Lifecycle.of(field).stampedOnce) record[key] = held[key];
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
store.set(keyOf(id), record);
|
|
390
|
-
return record;
|
|
391
|
-
},
|
|
392
|
-
async upsertAll(inputs: readonly Partial<Record<string, unknown>>[]) {
|
|
393
|
-
for (const input of inputs) await (this as any).upsert(input);
|
|
394
|
-
return inputs.length;
|
|
395
|
-
},
|
|
396
|
-
async create(input: Partial<Record<string, unknown>>) {
|
|
397
|
-
const record = applyCreate(fields, input);
|
|
398
|
-
const id = record[pk] as string | undefined;
|
|
399
|
-
// `primary(text())` declares no generator, so nothing fills the hole and the
|
|
400
|
-
// caller has to. Keying on `undefined` would let the second create overwrite the
|
|
401
|
-
// first, in silence — the old version hid this by inventing an `id` field the
|
|
402
|
-
// entity never declared.
|
|
403
|
-
if (id === undefined) {
|
|
404
|
-
throw new Error(`${name}.create: '${pk}' is the primary key and nothing supplied it — this entity declares no generator for it.`);
|
|
405
|
-
}
|
|
406
|
-
// A create is not an upsert. `Map.set` overwrites, so a second create under the
|
|
407
|
-
// same key answered "created" while destroying the previous row — SQL answers a
|
|
408
|
-
// constraint violation, and a store that loses data silently is worse than one
|
|
409
|
-
// that fails.
|
|
410
|
-
if (store.has(keyOf(id))) {
|
|
411
|
-
throw new Error(`${name}.create: '${pk}' ${JSON.stringify(id)} already exists.`);
|
|
412
|
-
}
|
|
413
|
-
store.set(keyOf(id), record);
|
|
414
|
-
return record;
|
|
415
|
-
},
|
|
416
|
-
async update(id: string, input: Partial<Record<string, unknown>>) {
|
|
417
|
-
const existing = store.get(keyOf(id));
|
|
418
|
-
if (!existing) throw new Error(`Not found: ${id}`);
|
|
419
|
-
const updated = { ...existing, ...applyUpdate(fields, input), [pk]: existing[pk] };
|
|
420
|
-
store.set(keyOf(id), updated);
|
|
421
|
-
return updated;
|
|
422
|
-
},
|
|
423
|
-
async delete(id: string) { return store.delete(keyOf(id)); },
|
|
424
|
-
output(_schema: SchemaView) { return this; },
|
|
425
|
-
};
|
|
426
|
-
}
|
package/src/index.ts
CHANGED
|
@@ -14,7 +14,6 @@ export {
|
|
|
14
14
|
extendFougere,
|
|
15
15
|
useFougereApp,
|
|
16
16
|
reloadFougere,
|
|
17
|
-
createMemoryOrm,
|
|
18
17
|
type FougereServerConfig,
|
|
19
18
|
} from './boot.js';
|
|
20
19
|
|
|
@@ -53,3 +52,6 @@ export { sessionViewOf, type SessionView } from './session.js';
|
|
|
53
52
|
export { stateFor } from './state.js';
|
|
54
53
|
|
|
55
54
|
export { serveGraphQL, type GraphQLRequest } from './graphql.js';
|
|
55
|
+
|
|
56
|
+
// Re-exported where every host already looks for it; it lives in its own adapter now.
|
|
57
|
+
export { createMemoryStorage } from '@fougere/adapter-memory';
|