@fougere/core 0.9.0-alpha.0 → 0.9.2-alpha.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/AppLifecycle.d.ts +5 -1
- package/dist/boot/AppLifecycle.d.ts.map +1 -1
- package/dist/boot/AppLifecycle.js.map +1 -1
- package/dist/boot/apply.d.ts +5 -1
- package/dist/boot/apply.d.ts.map +1 -1
- package/dist/boot/apply.js +5 -1
- package/dist/boot/apply.js.map +1 -1
- package/dist/boot/bootstrap.d.ts.map +1 -1
- package/dist/boot/bootstrap.js +21 -15
- package/dist/boot/bootstrap.js.map +1 -1
- package/dist/boot/card.d.ts.map +1 -1
- package/dist/boot/card.js +6 -1
- package/dist/boot/card.js.map +1 -1
- package/dist/boot/install.d.ts.map +1 -1
- package/dist/boot/install.js +18 -2
- package/dist/boot/install.js.map +1 -1
- package/dist/boot/ports.d.ts +23 -0
- package/dist/boot/ports.d.ts.map +1 -1
- package/dist/boot/ports.js +49 -0
- package/dist/boot/ports.js.map +1 -1
- package/dist/boot/remote.d.ts +5 -1
- package/dist/boot/remote.d.ts.map +1 -1
- package/dist/boot/remote.js.map +1 -1
- package/dist/boot/seed.d.ts +5 -1
- package/dist/boot/seed.d.ts.map +1 -1
- package/dist/boot/seed.js +5 -1
- package/dist/boot/seed.js.map +1 -1
- package/dist/boot/together.d.ts.map +1 -1
- package/dist/boot/together.js +5 -1
- package/dist/boot/together.js.map +1 -1
- package/dist/builtin/logger.d.ts +1 -2
- package/dist/builtin/logger.d.ts.map +1 -1
- package/dist/builtin/logger.js +0 -19
- package/dist/builtin/logger.js.map +1 -1
- package/dist/descriptor/frond.d.ts +5 -1
- package/dist/descriptor/frond.d.ts.map +1 -1
- package/dist/descriptor/frond.js.map +1 -1
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +5 -1
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/prefab/collector.d.ts +5 -1
- package/dist/prefab/collector.d.ts.map +1 -1
- package/dist/prefab/collector.js +5 -1
- package/dist/prefab/collector.js.map +1 -1
- package/dist/prefab/crud.d.ts +9 -5
- package/dist/prefab/crud.d.ts.map +1 -1
- package/dist/prefab/crud.js +9 -5
- package/dist/prefab/crud.js.map +1 -1
- package/dist/prefab/mirror.d.ts +5 -1
- package/dist/prefab/mirror.d.ts.map +1 -1
- package/dist/prefab/mirror.js.map +1 -1
- package/dist/prefab/presenter.d.ts +6 -2
- package/dist/prefab/presenter.d.ts.map +1 -1
- package/dist/prefab/presenter.js +6 -2
- package/dist/prefab/presenter.js.map +1 -1
- package/dist/prefab/repository.d.ts +5 -1
- package/dist/prefab/repository.d.ts.map +1 -1
- package/dist/prefab/repository.js.map +1 -1
- package/dist/source.d.ts +5 -1
- package/dist/source.d.ts.map +1 -1
- package/dist/source.js.map +1 -1
- package/dist/storage/port.d.ts +27 -1
- package/dist/storage/port.d.ts.map +1 -1
- package/dist/storage/port.js +70 -0
- package/dist/storage/port.js.map +1 -1
- package/dist/wire/emit.d.ts.map +1 -1
- package/dist/wire/emit.js +5 -1
- package/dist/wire/emit.js.map +1 -1
- package/dist/wire/errors.d.ts +5 -1
- package/dist/wire/errors.d.ts.map +1 -1
- package/dist/wire/errors.js +5 -1
- package/dist/wire/errors.js.map +1 -1
- package/package.json +4 -4
- package/src/boot/AppLifecycle.ts +5 -1
- package/src/boot/apply.ts +5 -1
- package/src/boot/bootstrap.ts +21 -15
- package/src/boot/card.ts +6 -1
- package/src/boot/install.ts +18 -3
- package/src/boot/ports.ts +63 -0
- package/src/boot/remote.ts +5 -1
- package/src/boot/seed.ts +5 -1
- package/src/boot/together.ts +5 -1
- package/src/builtin/logger.ts +1 -20
- package/src/descriptor/frond.ts +5 -1
- package/src/identity.ts +5 -1
- package/src/index.ts +4 -3
- package/src/prefab/collector.ts +5 -1
- package/src/prefab/crud.ts +9 -5
- package/src/prefab/mirror.ts +5 -1
- package/src/prefab/presenter.ts +6 -2
- package/src/prefab/repository.ts +5 -1
- package/src/source.ts +5 -1
- package/src/storage/port.ts +74 -1
- package/src/wire/emit.ts +5 -1
- package/src/wire/errors.ts +5 -1
package/src/prefab/collector.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Collector(Type) — resolves one handler input parameter from the invocation context.
|
|
3
|
+
*
|
|
4
|
+
* Documented: [collectors](https://fougere.dev/docs/business/collectors).
|
|
5
|
+
*/
|
|
2
6
|
|
|
3
7
|
import { upperFirst } from '@fougere/schema';
|
|
4
8
|
|
package/src/prefab/crud.ts
CHANGED
|
@@ -4,8 +4,8 @@ import type { OperationContract } from '../wire/operation.js';
|
|
|
4
4
|
import { targetOf } from './prefab.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* FR :
|
|
7
|
+
* A class is recognized by what it ANSWERS — the mixin leaves no other trace.
|
|
8
|
+
* FR : une classe se reconnaît à ce qu'elle répond, le mixin ne laissant rien d'autre.
|
|
9
9
|
* `inheritsCrud(class PostHandler extends Crud(Post) {})` → `true`
|
|
10
10
|
*/
|
|
11
11
|
export function inheritsCrud(ctor: unknown): boolean {
|
|
@@ -15,8 +15,8 @@ export function inheritsCrud(ctor: unknown): boolean {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
* FR :
|
|
18
|
+
* Storage follows the shape the handler was built on, which may differ from its address.
|
|
19
|
+
* FR : le stockage suit la forme sur laquelle le handler est bâti, pas son adresse.
|
|
20
20
|
* `subjectOf(class Draft extends Crud(Post) {}, 'draft')` → `'post'`
|
|
21
21
|
*/
|
|
22
22
|
export function subjectOf(ctor: unknown, address: string): string {
|
|
@@ -112,7 +112,11 @@ export interface CrudConstructor<T, V = {}> {
|
|
|
112
112
|
readonly __ops: Record<string, OperationContract>;
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* Mixin — extends Crud(Entity) to get all 5 typed CRUD methods.
|
|
117
|
+
*
|
|
118
|
+
* Documented: [handlers](https://fougere.dev/docs/business/handlers).
|
|
119
|
+
*/
|
|
116
120
|
export function Crud<E extends EntityConstructor, V extends CrudViews | EntityConstructor = {}>(
|
|
117
121
|
entity: E,
|
|
118
122
|
output?: V,
|
package/src/prefab/mirror.ts
CHANGED
|
@@ -11,7 +11,11 @@ export interface Refreshed {
|
|
|
11
11
|
ms: number;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* A paginated local copy of a source that cannot be queried directly.
|
|
16
|
+
*
|
|
17
|
+
* Documented: [the base](https://fougere.dev/docs/concepts/the-base).
|
|
18
|
+
*/
|
|
15
19
|
export interface MirrorOf<T> {
|
|
16
20
|
/** The copy's own storage — where a page lands. */
|
|
17
21
|
storage: Storage<T>;
|
package/src/prefab/presenter.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Presenter(Entity) — enriches an entity's output with computed fields.
|
|
3
|
+
*
|
|
4
|
+
* Documented: [presenters](https://fougere.dev/docs/business/presenters).
|
|
5
|
+
*/
|
|
2
6
|
|
|
3
7
|
import { upperFirst, type EntityConstructor } from '@fougere/schema';
|
|
4
8
|
|
|
@@ -8,7 +12,7 @@ import { upperFirst, type EntityConstructor } from '@fougere/schema';
|
|
|
8
12
|
*/
|
|
9
13
|
export type PresenterViews = Record<string, EntityConstructor | [EntityConstructor]>;
|
|
10
14
|
|
|
11
|
-
/** `Presenter(Order, { items. */
|
|
15
|
+
/** `Presenter(Order, { items: [OrderItemView] })` — the views its computed fields emit. */
|
|
12
16
|
export function Presenter<E extends EntityConstructor>(entity: E, views?: PresenterViews) {
|
|
13
17
|
class PresenterBase {
|
|
14
18
|
static readonly __entity = entity;
|
package/src/prefab/repository.ts
CHANGED
|
@@ -2,7 +2,11 @@ import { upperFirst, type EntityConstructor } from '@fougere/schema';
|
|
|
2
2
|
import type { Storage, ListOptions, ListResult, SelectOption } from '../storage/port.js';
|
|
3
3
|
import type { SchemaView } from '@fougere/schema';
|
|
4
4
|
|
|
5
|
-
/**
|
|
5
|
+
/**
|
|
6
|
+
* Repository(…entities) — who owns an entity's storage, and where its questions are named.
|
|
7
|
+
*
|
|
8
|
+
* Documented: [repositories](https://fougere.dev/docs/business/repositories).
|
|
9
|
+
*/
|
|
6
10
|
|
|
7
11
|
/**
|
|
8
12
|
* The shape a repository of ONE entity has — the port itself, plus whatever the subclass names on
|
package/src/source.ts
CHANGED
|
@@ -12,7 +12,11 @@ export function declares(schema: SchemaView, constraint: Constraint): boolean {
|
|
|
12
12
|
return Object.values(schema.getFields()).some((field) => Role.of(field).isUnique);
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* A place rows live, whatever realizes it.
|
|
17
|
+
*
|
|
18
|
+
* Documented: [sources](https://fougere.dev/docs/infra/sources).
|
|
19
|
+
*/
|
|
16
20
|
export interface Source {
|
|
17
21
|
storageFactory: StorageFactory;
|
|
18
22
|
/**
|
package/src/storage/port.ts
CHANGED
|
@@ -102,8 +102,81 @@ export interface Storage<T = Record<string, unknown>> {
|
|
|
102
102
|
delete(id: string): Promise<boolean>;
|
|
103
103
|
/** Returns a scoped storage that restricts all read results to the fields of the given schema. */
|
|
104
104
|
output(schema: SchemaView): Storage<T>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* What each link of a chain stands in front of.
|
|
109
|
+
*
|
|
110
|
+
* A SYMBOL on the instance, set through a cast so it joins no declaration: `Storage` is an
|
|
111
|
+
* interface as well as a class, and the realizations satisfy it structurally —
|
|
112
|
+
* `storageOver` returns an object literal, and one more member would stop it being a
|
|
113
|
+
* storage. A `#private` field says the same thing and makes the class NOMINAL, which
|
|
114
|
+
* refuses every realization at once.
|
|
115
|
+
*
|
|
116
|
+
* On the instance and not in a `WeakMap` beside it, because `StorageGuard.guard` hands out
|
|
117
|
+
* `Object.create(storage)` — a new object whose prototype is the link. A symbol is found
|
|
118
|
+
* through that chain; a map keyed on the link is not, and the guarded object read
|
|
119
|
+
* `undefined`.
|
|
120
|
+
*/
|
|
121
|
+
const BEHIND = Symbol('fougere.storage.behind');
|
|
122
|
+
|
|
123
|
+
const behind = <T>(link: object): Storage<T> =>
|
|
124
|
+
(link as Record<symbol, unknown>)[BEHIND] as Storage<T>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* A storage that stands in front of another — the base a wrapper extends, and the only
|
|
128
|
+
* thing that makes `Storage` a seam rather than a shape.
|
|
129
|
+
*
|
|
130
|
+
* Merged with the interface above, so the class carries the thirteen gestures as a TYPE
|
|
131
|
+
* while its prototype carries them as a FORWARD. A wrapper writes what it changes and
|
|
132
|
+
* nothing else:
|
|
133
|
+
*
|
|
134
|
+
* ```ts
|
|
135
|
+
* class Audit extends Storage {
|
|
136
|
+
* constructor(private inner: Storage) { super(inner); }
|
|
137
|
+
* async create(row) { await say(row); return this.inner.create(row); }
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*
|
|
141
|
+
* `ports: { Storage: ['Audit'] }` orders the chain when a frond declares two, which is the
|
|
142
|
+
* same key, the same order and the same refusals a port gets. A realization does not extend
|
|
143
|
+
* this: it is handed in by `storageFactory` and is the last link, so what a wrapper does not
|
|
144
|
+
* override reaches it through these forwards.
|
|
145
|
+
*
|
|
146
|
+
* Documented: [storage](https://fougere.dev/docs/business/storage) and
|
|
147
|
+
* [ports](https://fougere.dev/docs/business/ports).
|
|
148
|
+
*/
|
|
149
|
+
export abstract class Storage<T = Record<string, unknown>> {
|
|
150
|
+
constructor(inner: Storage<T>) {
|
|
151
|
+
(this as Record<symbol, unknown>)[BEHIND] = inner;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
list(options?: ListOptions & SelectOption): Promise<ListResult<T>> { return behind<T>(this).list(options); }
|
|
155
|
+
findById(id: string, options?: SelectOption): Promise<T | undefined> { return behind<T>(this).findById(id, options); }
|
|
156
|
+
findBy(criteria: Partial<T> | Record<string, unknown>, options?: SelectOption): Promise<T | undefined> {
|
|
157
|
+
return behind<T>(this).findBy(criteria, options);
|
|
158
|
+
}
|
|
159
|
+
findAllBy(criteria: Partial<T> | Record<string, unknown>, options?: SelectOption): Promise<T[]> {
|
|
160
|
+
return behind<T>(this).findAllBy(criteria, options);
|
|
161
|
+
}
|
|
162
|
+
findByKeys(ids: readonly string[], options?: SelectOption): Promise<Map<string, T>> {
|
|
163
|
+
return behind<T>(this).findByKeys(ids, options);
|
|
164
|
+
}
|
|
165
|
+
findAllByKeys(field: string, keys: readonly string[], options?: SelectOption): Promise<Map<string, T[]>> {
|
|
166
|
+
return behind<T>(this).findAllByKeys(field, keys, options);
|
|
167
|
+
}
|
|
168
|
+
create(input: Partial<T>, options?: SelectOption): Promise<T> { return behind<T>(this).create(input, options); }
|
|
169
|
+
upsert(input: Partial<T>, options?: SelectOption): Promise<T> { return behind<T>(this).upsert(input, options); }
|
|
170
|
+
upsertAll(inputs: readonly Partial<T>[], options?: SelectOption): Promise<number> {
|
|
171
|
+
return behind<T>(this).upsertAll(inputs, options);
|
|
172
|
+
}
|
|
173
|
+
update(id: string, input: Partial<T>, options?: SelectOption): Promise<T> {
|
|
174
|
+
return behind<T>(this).update(id, input, options);
|
|
175
|
+
}
|
|
176
|
+
delete(id: string): Promise<boolean> { return behind<T>(this).delete(id); }
|
|
177
|
+
output(schema: SchemaView): Storage<T> { return behind<T>(this).output(schema); }
|
|
105
178
|
/** What this storage wraps — the Kysely instance for the SQL one, something else elsewhere. */
|
|
106
|
-
|
|
179
|
+
get client(): unknown { return behind<T>(this).client; }
|
|
107
180
|
}
|
|
108
181
|
|
|
109
182
|
/**
|
package/src/wire/emit.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Announcing a fact — the half of the topology `remotes:` never covered.
|
|
3
|
+
*
|
|
4
|
+
* Documented: [facts](https://fougere.dev/docs/business/facts).
|
|
5
|
+
*/
|
|
2
6
|
import { lowerFirst } from '@fougere/schema';
|
|
3
7
|
|
|
4
8
|
/**
|
package/src/wire/errors.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* The error vocabulary — what a refusal IS, independently of who hears it.
|
|
3
|
+
*
|
|
4
|
+
* Documented: [errors](https://fougere.dev/docs/business/errors).
|
|
5
|
+
*/
|
|
2
6
|
|
|
3
7
|
import type { ValidationError } from '@fougere/schema';
|
|
4
8
|
|