@fabrika/db 0.0.0-stage → 0.4.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.
@@ -0,0 +1,26 @@
1
+ // @fabrika/db/production — whether this process serves an application. The generated entrypoint marks it before it
2
+ // imports the application, and the test kits refuse to load or run once it is marked. The mark is one non-writable,
3
+ // non-configurable property of `globalThis` under a registered symbol, so every installed copy of this package reads
4
+ // the same mark, it survives the scrub of the framework's variables (`FABRIKA_RELEASE` included), and nothing unmarks
5
+ // it. Browser- and Worker-safe.
6
+
7
+ const PRODUCTION = Symbol.for('fabrika.production')
8
+
9
+ /** Marks this process as one that serves an application; called by the generated entrypoint only. */
10
+ export function markProductionProcess(): void {
11
+ if (isProductionProcess()) {
12
+ return
13
+ }
14
+ Object.defineProperty(globalThis, PRODUCTION, { value: true, writable: false, configurable: false, enumerable: false })
15
+ }
16
+
17
+ export function isProductionProcess(): boolean {
18
+ return Reflect.get(globalThis, PRODUCTION) === true
19
+ }
20
+
21
+ /** Throws when this process serves an application: `what` is a test helper, which production never runs. */
22
+ export function refuseInProduction(what: string): void {
23
+ if (isProductionProcess()) {
24
+ throw new Error(`${what} is a test helper; this process serves an application, so it neither loads nor runs here`)
25
+ }
26
+ }
@@ -0,0 +1,57 @@
1
+ // Which objects `scoped` created, and the framework side of each. Module-private state: the only readers are
2
+ // `store.ts`, which registers and builds the framework's stores, `framework.ts`, which `@fabrika/app` alone imports, and `testing.ts`, which only test
3
+ // files may import.
4
+
5
+ import type { FileTables } from './file-tables'
6
+ import type { FormAdmissions, InboxQuota } from './form-admissions'
7
+ import type { WebhookTables } from './framework-tables'
8
+ import type { JobLeases } from './job-leases'
9
+ import type { DataAccess } from './orm'
10
+ import type { DataLayerRuntime, TableContext, TableProbe } from './store'
11
+
12
+ /** Answers what the framework's access check reads from the database: an object's containers, by dimension. */
13
+ export type Locator = (dimension: string, id: string) => Promise<ReadonlyMap<string, string> | null>
14
+
15
+ /** What the framework writes itself: a form's inbox row and its own `fabrika_*` tables. Usable once bound. */
16
+ export interface FrameworkTables {
17
+ /** Why `fields` of form `form` cannot be appended to an inbox table of this layer; empty when they can. */
18
+ inboxProblems(form: string, fields: readonly string[]): readonly string[]
19
+ /**
20
+ * Appends one row of `values` (column → value) to the inbox table of `form`, taking one from `quota` in the same
21
+ * transaction; `false`, with nothing written, when the bucket is full.
22
+ */
23
+ appendToInbox(form: string, values: Readonly<Record<string, unknown>>, quota: InboxQuota): Promise<boolean>
24
+ readonly webhooks: WebhookTables
25
+ readonly jobs: JobLeases
26
+ /** A form's admission counters and the challenge tokens it accepted. */
27
+ readonly forms: FormAdmissions
28
+ }
29
+
30
+ export interface FrameworkSide {
31
+ /** Connects the layer once and answers its locator; a second call throws. */
32
+ bind(runtime: DataLayerRuntime): Locator
33
+ /** The rows of the file collections' tables; usable once bound. */
34
+ readonly files: FileTables
35
+ readonly framework: FrameworkTables
36
+ /** The untyped handle over one table that `@fabrika/db/testing` hands the isolation tests. */
37
+ probe(table: string): TableProbe
38
+ /** One table's context, for the framework's own store builders (`defineStore`, `@fabrika/db/testing`). */
39
+ tableContext(table: string, mode: 'dimension' | 'child'): TableContext
40
+ /** The mini-ORM: invocation transactions and the handles of `ctx.db`; usable once bound. */
41
+ readonly data: DataAccess
42
+ }
43
+
44
+ // Captured when the module loads, before application code: a later patch to WeakMap does not change the registry.
45
+ const registry = new WeakMap<object, FrameworkSide>()
46
+ const weakGet: (this: WeakMap<object, FrameworkSide>, key: object) => FrameworkSide | undefined = WeakMap.prototype.get
47
+ const weakSet: (this: WeakMap<object, FrameworkSide>, key: object, value: FrameworkSide) => WeakMap<object, FrameworkSide> = WeakMap.prototype.set
48
+ const apply = Reflect.apply
49
+
50
+ export function register(database: object, side: FrameworkSide): void {
51
+ apply(weakSet, registry, [database, side])
52
+ }
53
+
54
+ /** The framework side of an object `scoped` created; undefined for anything else, a structural copy included. */
55
+ export function frameworkSideOf(value: unknown): FrameworkSide | undefined {
56
+ return typeof value === 'object' && value !== null ? apply(weakGet, registry, [value]) : undefined
57
+ }