@opetope/core 0.1.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/CHANGELOG.md +5 -0
- package/LICENSE +21 -0
- package/README.md +250 -0
- package/README.ru.md +246 -0
- package/dist/abort-compat.d.ts +10 -0
- package/dist/abort-compat.js +2 -0
- package/dist/abort-compat.js.map +1 -0
- package/dist/adapter-method.d.ts +27 -0
- package/dist/attachment-lifecycle-cleanup.d.ts +3 -0
- package/dist/attachment-lifecycle-cleanup.js +2 -0
- package/dist/attachment-lifecycle-cleanup.js.map +1 -0
- package/dist/attachment-lifecycle-contract.d.ts +260 -0
- package/dist/attachment-lifecycle-contract.js +2 -0
- package/dist/attachment-lifecycle-contract.js.map +1 -0
- package/dist/attachment-lifecycle-helpers.d.ts +34 -0
- package/dist/attachment-lifecycle-helpers.js +2 -0
- package/dist/attachment-lifecycle-helpers.js.map +1 -0
- package/dist/attachment-lifecycle-machine.d.ts +3 -0
- package/dist/attachment-lifecycle-machine.js +2 -0
- package/dist/attachment-lifecycle-machine.js.map +1 -0
- package/dist/attachment-lifecycle-mailbox.d.ts +10 -0
- package/dist/attachment-lifecycle-mailbox.js +2 -0
- package/dist/attachment-lifecycle-mailbox.js.map +1 -0
- package/dist/attachment-lifecycle-open.d.ts +3 -0
- package/dist/attachment-lifecycle-open.js +2 -0
- package/dist/attachment-lifecycle-open.js.map +1 -0
- package/dist/attachment-lifecycle.d.ts +4 -0
- package/dist/attachment-lifecycle.js +2 -0
- package/dist/attachment-lifecycle.js.map +1 -0
- package/dist/attachment.d.ts +49 -0
- package/dist/attachment.js +2 -0
- package/dist/attachment.js.map +1 -0
- package/dist/call-authority.d.ts +26 -0
- package/dist/call-controller-support.d.ts +77 -0
- package/dist/call-controller-support.js +2 -0
- package/dist/call-controller-support.js.map +1 -0
- package/dist/call-controller.d.ts +49 -0
- package/dist/call-controller.js +2 -0
- package/dist/call-controller.js.map +1 -0
- package/dist/call-execution-inspection.d.ts +26 -0
- package/dist/call-execution-inspection.js +2 -0
- package/dist/call-execution-inspection.js.map +1 -0
- package/dist/call-executor-factory.d.ts +5 -0
- package/dist/call-executor-factory.js +2 -0
- package/dist/call-executor-factory.js.map +1 -0
- package/dist/call-executor-record.d.ts +66 -0
- package/dist/call-executor-record.js +2 -0
- package/dist/call-executor-record.js.map +1 -0
- package/dist/call-executor-support.d.ts +25 -0
- package/dist/call-executor-support.js +2 -0
- package/dist/call-executor-support.js.map +1 -0
- package/dist/call-executor-types.d.ts +56 -0
- package/dist/call-executor-waiters.d.ts +23 -0
- package/dist/call-executor-waiters.js +2 -0
- package/dist/call-executor-waiters.js.map +1 -0
- package/dist/call-executor.d.ts +6 -0
- package/dist/call-executor.js +2 -0
- package/dist/call-executor.js.map +1 -0
- package/dist/call-invocation.d.ts +61 -0
- package/dist/call-invocation.js +2 -0
- package/dist/call-invocation.js.map +1 -0
- package/dist/call-lane.d.ts +28 -0
- package/dist/call-lane.js +2 -0
- package/dist/call-lane.js.map +1 -0
- package/dist/call-target-result.d.ts +22 -0
- package/dist/call-target-result.js +2 -0
- package/dist/call-target-result.js.map +1 -0
- package/dist/call-target.d.ts +42 -0
- package/dist/call-target.js +2 -0
- package/dist/call-target.js.map +1 -0
- package/dist/call.d.ts +11 -0
- package/dist/call.js +2 -0
- package/dist/call.js.map +1 -0
- package/dist/contribution-hub.d.ts +100 -0
- package/dist/contribution-hub.js +2 -0
- package/dist/contribution-hub.js.map +1 -0
- package/dist/contribution-transaction.d.ts +20 -0
- package/dist/contribution-transaction.js +2 -0
- package/dist/contribution-transaction.js.map +1 -0
- package/dist/contribution.d.ts +64 -0
- package/dist/contribution.js +2 -0
- package/dist/contribution.js.map +1 -0
- package/dist/data-scheduler.d.ts +4 -0
- package/dist/data-scheduler.js +2 -0
- package/dist/data-scheduler.js.map +1 -0
- package/dist/errors.d.ts +56 -0
- package/dist/errors.js +2 -0
- package/dist/errors.js.map +1 -0
- package/dist/identity.d.ts +6 -0
- package/dist/identity.js +2 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/dist/internal.d.ts +46 -0
- package/dist/internal.js +2 -0
- package/dist/internal.js.map +1 -0
- package/dist/lifetime.d.ts +19 -0
- package/dist/lifetime.js +2 -0
- package/dist/lifetime.js.map +1 -0
- package/dist/model-context.d.ts +155 -0
- package/dist/model.d.ts +21 -0
- package/dist/model.js +2 -0
- package/dist/model.js.map +1 -0
- package/dist/platform-compat.d.ts +9 -0
- package/dist/platform-compat.js +2 -0
- package/dist/platform-compat.js.map +1 -0
- package/dist/port.d.ts +26 -0
- package/dist/port.js +2 -0
- package/dist/port.js.map +1 -0
- package/dist/reactive-collection.d.ts +27 -0
- package/dist/reactive-collection.js +2 -0
- package/dist/reactive-collection.js.map +1 -0
- package/dist/reactive-node.d.ts +62 -0
- package/dist/reactive-node.js +2 -0
- package/dist/reactive-node.js.map +1 -0
- package/dist/reactive-scheduler-control.d.ts +34 -0
- package/dist/reactive-scheduler-control.js +2 -0
- package/dist/reactive-scheduler-control.js.map +1 -0
- package/dist/reactive-scheduler.d.ts +18 -0
- package/dist/reactive-scheduler.js +2 -0
- package/dist/reactive-scheduler.js.map +1 -0
- package/dist/reactive.d.ts +41 -0
- package/dist/reactive.js +2 -0
- package/dist/reactive.js.map +1 -0
- package/dist/readable.d.ts +13 -0
- package/dist/readable.js +2 -0
- package/dist/readable.js.map +1 -0
- package/dist/resource.d.ts +82 -0
- package/dist/type-helpers.d.ts +14 -0
- package/package.json +66 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { Lookup } from './reactive-collection.js';
|
|
2
|
+
import type { Equality, ExternalReadableSource, ReactiveRead } from './reactive-scheduler.js';
|
|
3
|
+
import type { Readable } from './readable.js';
|
|
4
|
+
type ReadableValue<Source> = Source extends Readable<infer Value> ? Value : never;
|
|
5
|
+
type ReadableValues<Sources extends readonly Readable<unknown>[]> = {
|
|
6
|
+
readonly [Index in keyof Sources]: ReadableValue<Sources[Index]>;
|
|
7
|
+
};
|
|
8
|
+
interface ComputedOptions<Value> {
|
|
9
|
+
readonly equals?: Equality<Value>;
|
|
10
|
+
readonly read: (get: ReactiveRead) => Value;
|
|
11
|
+
}
|
|
12
|
+
interface DeriveOptions<Source, Value> {
|
|
13
|
+
readonly equals?: Equality<Value>;
|
|
14
|
+
readonly from: Readable<Source>;
|
|
15
|
+
readonly select: (source: Source) => Value;
|
|
16
|
+
}
|
|
17
|
+
interface DeriveManyOptions<Sources extends readonly Readable<unknown>[], Value> {
|
|
18
|
+
readonly equals?: Equality<Value>;
|
|
19
|
+
readonly from: Sources;
|
|
20
|
+
readonly select: (...sources: ReadableValues<Sources>) => Value;
|
|
21
|
+
}
|
|
22
|
+
declare function computed<Value>(options: ComputedOptions<Value>): Readable<Value>;
|
|
23
|
+
declare function isReadable(value: unknown): value is Readable<unknown>;
|
|
24
|
+
interface FromOptionalOptions<Value> {
|
|
25
|
+
readonly equals?: Equality<Value>;
|
|
26
|
+
/** What the consumer reads while the provider is absent: a weak edge answers, it does not fail (D105). */
|
|
27
|
+
readonly missing: Value;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* D187: the data half of a weak edge. `select` runs only on a `found` lookup and may return either a value or the
|
|
31
|
+
* provider's own `Readable`; the nested readable is read through `get`, so it is tracked while the provider is there
|
|
32
|
+
* and released the moment the lookup goes back to `missing`. A new provider instance is a new lookup, so the
|
|
33
|
+
* selection follows it without the consumer holding the old one.
|
|
34
|
+
*/
|
|
35
|
+
declare function fromOptional<Found, Value>(source: Readable<Lookup<Found>>, select: (found: Found) => Readable<Value> | Value, options: FromOptionalOptions<Value>): Readable<Value>;
|
|
36
|
+
declare function derive<Source, Value>(options: DeriveOptions<Source, Value>): Readable<Value>;
|
|
37
|
+
declare function derive<Sources extends readonly Readable<unknown>[], Value>(options: DeriveManyOptions<Sources, Value>): Readable<Value>;
|
|
38
|
+
declare function externalReadable<Value>(source: ExternalReadableSource<Value>): Readable<Value>;
|
|
39
|
+
declare function externalReadable<Source, Value>(source: ExternalReadableSource<Source>, select: (source: Source) => Value, equals?: Equality<Value>): Readable<Value>;
|
|
40
|
+
export { computed, derive, externalReadable, fromOptional, isReadable };
|
|
41
|
+
export type { ComputedOptions, DeriveManyOptions, DeriveOptions, Equality, ExternalReadableSource, ReactiveRead, ReadableValue, ReadableValues, };
|
package/dist/reactive.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{reactiveComputed as i,defaultEquality as a,reactiveDerived as f,reactiveExternal as o}from"./reactive-scheduler.js";function s(e){return i(e.read,e.equals??a)}function l(e){if(typeof e!="object"||e===null)return!1;const r=e;return typeof r.getSnapshot=="function"&&typeof r.subscribe=="function"}function d(e,r,n){return s({...n.equals===void 0?{}:{equals:n.equals},read:t=>{const u=t(e);if(u.kind==="missing")return n.missing;const c=r(u.value);return l(c)?t(c):c}})}function m(e){if(l(e.from)){const t=e.from,u=e.select;return f([t],c=>u(c(t)),e.equals??a)}const r=[...e.from],n=e.select;return f(r,t=>n(...r.map(u=>t(u))),e.equals??a)}function q(e,r,n){return o(e,r??(t=>t),n??a)}export{s as computed,m as derive,q as externalReadable,d as fromOptional,l as isReadable};
|
|
2
|
+
//# sourceMappingURL=reactive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reactive.js","sources":["../src/reactive.ts"],"sourcesContent":["import type { Lookup } from './reactive-collection';\nimport { defaultEquality, reactiveComputed, reactiveDerived, reactiveExternal } from './reactive-scheduler';\nimport type { Equality, ExternalReadableSource, ReactiveRead } from './reactive-scheduler';\nimport type { Readable } from './readable';\n\ntype ReadableValue<Source> = Source extends Readable<infer Value> ? Value : never;\ntype ReadableValues<Sources extends readonly Readable<unknown>[]> = {\n readonly [Index in keyof Sources]: ReadableValue<Sources[Index]>;\n};\n\ninterface ComputedOptions<Value> {\n readonly equals?: Equality<Value>;\n readonly read: (get: ReactiveRead) => Value;\n}\n\ninterface DeriveOptions<Source, Value> {\n readonly equals?: Equality<Value>;\n readonly from: Readable<Source>;\n readonly select: (source: Source) => Value;\n}\n\ninterface DeriveManyOptions<Sources extends readonly Readable<unknown>[], Value> {\n readonly equals?: Equality<Value>;\n readonly from: Sources;\n readonly select: (...sources: ReadableValues<Sources>) => Value;\n}\n\nfunction computed<Value>(options: ComputedOptions<Value>): Readable<Value> {\n return reactiveComputed(options.read, options.equals ?? defaultEquality);\n}\n\nfunction isReadable(value: unknown): value is Readable<unknown> {\n if (typeof value !== 'object' || value === null) return false;\n\n const readable = value as Partial<Readable<unknown>>;\n\n return typeof readable.getSnapshot === 'function' && typeof readable.subscribe === 'function';\n}\n\ninterface FromOptionalOptions<Value> {\n readonly equals?: Equality<Value>;\n /** What the consumer reads while the provider is absent: a weak edge answers, it does not fail (D105). */\n readonly missing: Value;\n}\n\n/**\n * D187: the data half of a weak edge. `select` runs only on a `found` lookup and may return either a value or the\n * provider's own `Readable`; the nested readable is read through `get`, so it is tracked while the provider is there\n * and released the moment the lookup goes back to `missing`. A new provider instance is a new lookup, so the\n * selection follows it without the consumer holding the old one.\n */\nfunction fromOptional<Found, Value>(\n source: Readable<Lookup<Found>>,\n select: (found: Found) => Readable<Value> | Value,\n options: FromOptionalOptions<Value>,\n): Readable<Value> {\n return computed({\n ...(options.equals === undefined ? {} : { equals: options.equals }),\n read: get => {\n const lookup = get(source);\n\n if (lookup.kind === 'missing') return options.missing;\n\n const selected = select(lookup.value);\n\n return isReadable(selected) ? get(selected) : selected;\n },\n });\n}\n\nfunction derive<Source, Value>(options: DeriveOptions<Source, Value>): Readable<Value>;\nfunction derive<Sources extends readonly Readable<unknown>[], Value>(\n options: DeriveManyOptions<Sources, Value>,\n): Readable<Value>;\nfunction derive<Value>(\n options: DeriveManyOptions<readonly Readable<unknown>[], Value> | DeriveOptions<unknown, Value>,\n): Readable<Value> {\n if (isReadable(options.from)) {\n const source = options.from;\n const select = (options as DeriveOptions<unknown, Value>).select;\n\n return reactiveDerived([source], get => select(get(source)), options.equals ?? defaultEquality);\n }\n\n const sources = [...options.from];\n const select = (options as DeriveManyOptions<readonly Readable<unknown>[], Value>).select;\n\n return reactiveDerived(\n sources,\n get => select(...sources.map(source => get(source))),\n options.equals ?? defaultEquality,\n );\n}\n\nfunction externalReadable<Value>(source: ExternalReadableSource<Value>): Readable<Value>;\nfunction externalReadable<Source, Value>(\n source: ExternalReadableSource<Source>,\n select: (source: Source) => Value,\n equals?: Equality<Value>,\n): Readable<Value>;\nfunction externalReadable<Source, Value = Source>(\n source: ExternalReadableSource<Source>,\n select?: (source: Source) => Value,\n equals?: Equality<Value>,\n): Readable<Source | Value> {\n return reactiveExternal(\n source,\n (select ?? ((value: Source) => value)) as (source: Source) => Source | Value,\n (equals ?? defaultEquality) as Equality<Source | Value>,\n );\n}\n\nexport { computed, derive, externalReadable, fromOptional, isReadable };\nexport type {\n ComputedOptions,\n DeriveManyOptions,\n DeriveOptions,\n Equality,\n ExternalReadableSource,\n ReactiveRead,\n ReadableValue,\n ReadableValues,\n};\n"],"names":["computed","options","reactiveComputed","defaultEquality","isReadable","value","readable","fromOptional","source","select","get","lookup","selected","derive","reactiveDerived","sources","externalReadable","equals","reactiveExternal"],"mappings":"2HA2BA,SAASA,EAAgBC,EAA+B,CACtD,OAAOC,EAAiBD,EAAQ,KAAMA,EAAQ,QAAUE,CAAe,CACzE,CAEA,SAASC,EAAWC,EAAc,CAChC,GAAI,OAAOA,GAAU,UAAYA,IAAU,KAAM,MAAO,GAExD,MAAMC,EAAWD,EAEjB,OAAO,OAAOC,EAAS,aAAgB,YAAc,OAAOA,EAAS,WAAc,UACrF,CAcA,SAASC,EACPC,EACAC,EACAR,EAAmC,CAEnC,OAAOD,EAAS,CACd,GAAIC,EAAQ,SAAW,OAAY,CAAA,EAAK,CAAE,OAAQA,EAAQ,QAC1D,KAAMS,GAAM,CACV,MAAMC,EAASD,EAAIF,CAAM,EAEzB,GAAIG,EAAO,OAAS,UAAW,OAAOV,EAAQ,QAE9C,MAAMW,EAAWH,EAAOE,EAAO,KAAK,EAEpC,OAAOP,EAAWQ,CAAQ,EAAIF,EAAIE,CAAQ,EAAIA,CAChD,CACD,CAAA,CACH,CAMA,SAASC,EACPZ,EAA+F,CAE/F,GAAIG,EAAWH,EAAQ,IAAI,EAAG,CAC5B,MAAMO,EAASP,EAAQ,KACjBQ,EAAUR,EAA0C,OAE1D,OAAOa,EAAgB,CAACN,CAAM,EAAGE,GAAOD,EAAOC,EAAIF,CAAM,CAAC,EAAGP,EAAQ,QAAUE,CAAe,CAChG,CAEA,MAAMY,EAAU,CAAC,GAAGd,EAAQ,IAAI,EAC1BQ,EAAUR,EAAmE,OAEnF,OAAOa,EACLC,EACAL,GAAOD,EAAO,GAAGM,EAAQ,IAAIP,GAAUE,EAAIF,CAAM,CAAC,CAAC,EACnDP,EAAQ,QAAUE,CAAe,CAErC,CAQA,SAASa,EACPR,EACAC,EACAQ,EAAwB,CAExB,OAAOC,EACLV,EACCC,IAAYJ,GAAkBA,GAC9BY,GAAUd,CAAe,CAE9B"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type ReadableListener = () => void;
|
|
2
|
+
interface Readable<T> {
|
|
3
|
+
getSnapshot(): T;
|
|
4
|
+
subscribe(listener: ReadableListener): () => void;
|
|
5
|
+
}
|
|
6
|
+
interface State<T> extends Readable<T> {
|
|
7
|
+
readonly close: () => void;
|
|
8
|
+
readonly set: (value: T) => void;
|
|
9
|
+
readonly update: (update: (current: T) => T) => void;
|
|
10
|
+
}
|
|
11
|
+
declare function createState<T>(initialValue: T): State<T>;
|
|
12
|
+
export { createState };
|
|
13
|
+
export type { Readable, ReadableListener, State };
|
package/dist/readable.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{endDataTransaction as f,beginDataTransaction as b}from"./data-scheduler.js";import{ReadableError as d}from"./errors.js";import{createAggregateError as p}from"./platform-compat.js";const h=()=>{},u=Symbol("opetope.closed-readable-state");function m(o){try{return f(),o}catch(e){const r=o??[];return r.push(e),r}}function y(o){let e;for(const{listener:r}of o)try{r()}catch(a){(e??(e=[])).push(a)}return e}function w(o){let e=o,r=!1;const a=new Set,i=()=>{if(r)throw new d("closed","Cannot update a closed readable state.")},c=()=>{if(e===u)throw new d("closed","Cannot read a closed readable state.");return e},l=()=>{if(a.size===0)return;const n=[...a];let t;b();try{t=y(n)}finally{t=m(t)}if(t!==void 0)throw p(t,"Readable listeners failed after the value was committed.")};return Object.freeze({close(){if(!r){r=!0,e=u;try{l()}finally{a.clear()}}},getSnapshot(){return c()},set(n){i(),!Object.is(c(),n)&&(e=n,l())},subscribe(n){if(r)return h;const t={listener:n};a.add(t);let s=!0;return()=>{s&&(s=!1,a.delete(t))}},update(n){i();const t=c(),s=n(t);i(),!Object.is(t,s)&&(e=s,l())}})}export{w as createState};
|
|
2
|
+
//# sourceMappingURL=readable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readable.js","sources":["../src/readable.ts"],"sourcesContent":["import { beginDataTransaction, endDataTransaction } from './data-scheduler';\nimport { ReadableError } from './errors';\nimport { createAggregateError } from './platform-compat';\n\ntype ReadableListener = () => void;\n\ninterface Readable<T> {\n getSnapshot(): T;\n subscribe(listener: ReadableListener): () => void;\n}\n\ninterface State<T> extends Readable<T> {\n readonly close: () => void;\n readonly set: (value: T) => void;\n readonly update: (update: (current: T) => T) => void;\n}\n\nconst noop = (): void => undefined;\nconst closedReadableState = Symbol('opetope.closed-readable-state');\n\ntype ListenerRegistration = { readonly listener: ReadableListener };\n\nfunction endDataTransactionSafely(failures: unknown[] | undefined): unknown[] | undefined {\n try {\n endDataTransaction();\n\n return failures;\n } catch (error) {\n const next = failures ?? [];\n next.push(error);\n\n return next;\n }\n}\n\nfunction notifyReadableListeners(listeners: readonly ListenerRegistration[]): unknown[] | undefined {\n let failures: unknown[] | undefined;\n\n for (const { listener } of listeners) {\n try {\n listener();\n } catch (error) {\n (failures ??= []).push(error);\n }\n }\n\n return failures;\n}\n\nfunction createState<T>(initialValue: T): State<T> {\n let current: typeof closedReadableState | T = initialValue;\n let closed = false;\n const listeners = new Set<ListenerRegistration>();\n\n const assertOpen = (): void => {\n if (closed) throw new ReadableError('closed', 'Cannot update a closed readable state.');\n };\n\n const readCurrent = (): T => {\n if (current === closedReadableState) {\n throw new ReadableError('closed', 'Cannot read a closed readable state.');\n }\n\n return current;\n };\n\n const publish = (): void => {\n if (listeners.size === 0) return;\n\n const notified = [...listeners];\n let failures: unknown[] | undefined;\n\n beginDataTransaction();\n\n try {\n failures = notifyReadableListeners(notified);\n } finally {\n failures = endDataTransactionSafely(failures);\n }\n\n if (failures !== undefined) {\n throw createAggregateError(failures, 'Readable listeners failed after the value was committed.');\n }\n };\n\n return Object.freeze({\n /**\n * Closing is a change like any other: dependents hear it once, and the read that follows fails instead of\n * handing out the last value of a source nobody owns any more. A `derive` or `computed` recomputes inside this\n * transaction, reads a closed source and keeps that failure, so the whole chain answers `closed` (D146).\n */\n close(): void {\n if (closed) return;\n\n closed = true;\n current = closedReadableState;\n\n try {\n publish();\n } finally {\n listeners.clear();\n }\n },\n getSnapshot(): T {\n return readCurrent();\n },\n set(value: T): void {\n assertOpen();\n\n if (Object.is(readCurrent(), value)) return;\n\n current = value;\n publish();\n },\n subscribe(listener: ReadableListener): () => void {\n if (closed) return noop;\n\n const registration = { listener };\n listeners.add(registration);\n let subscribed = true;\n\n return (): void => {\n if (!subscribed) return;\n\n subscribed = false;\n listeners.delete(registration);\n };\n },\n update(update: (current: T) => T): void {\n assertOpen();\n const previous = readCurrent();\n const next = update(previous);\n // D201: the updater is foreign code and may close this state; closing is workspace, so what it computed for the\n // world before the close never lands.\n assertOpen();\n\n if (Object.is(previous, next)) return;\n\n current = next;\n publish();\n },\n });\n}\n\nexport { createState };\nexport type { Readable, ReadableListener, State };\n"],"names":["noop","closedReadableState","endDataTransactionSafely","failures","endDataTransaction","error","next","notifyReadableListeners","listeners","listener","createState","initialValue","current","closed","assertOpen","ReadableError","readCurrent","publish","notified","beginDataTransaction","createAggregateError","value","registration","subscribed","update","previous"],"mappings":"2LAiBA,MAAMA,EAAO,IAAA,GACPC,EAAsB,OAAO,+BAA+B,EAIlE,SAASC,EAAyBC,EAA+B,CAC/D,GAAI,CACF,OAAAC,EAAkB,EAEXD,CACT,OAASE,EAAO,CACd,MAAMC,EAAOH,GAAY,CAAA,EACzB,OAAAG,EAAK,KAAKD,CAAK,EAERC,CACT,CACF,CAEA,SAASC,EAAwBC,EAA0C,CACzE,IAAIL,EAEJ,SAAW,CAAE,SAAAM,CAAQ,IAAMD,EACzB,GAAI,CACFC,EAAQ,CACV,OAASJ,EAAO,EACbF,MAAa,CAAA,IAAI,KAAKE,CAAK,CAC9B,CAGF,OAAOF,CACT,CAEA,SAASO,EAAeC,EAAe,CACrC,IAAIC,EAA0CD,EAC1CE,EAAS,GACb,MAAML,EAAY,IAAI,IAEhBM,EAAa,IAAW,CAC5B,GAAID,EAAQ,MAAM,IAAIE,EAAc,SAAU,wCAAwC,CACxF,EAEMC,EAAc,IAAQ,CAC1B,GAAIJ,IAAYX,EACd,MAAM,IAAIc,EAAc,SAAU,sCAAsC,EAG1E,OAAOH,CACT,EAEMK,EAAU,IAAW,CACzB,GAAIT,EAAU,OAAS,EAAG,OAE1B,MAAMU,EAAW,CAAC,GAAGV,CAAS,EAC9B,IAAIL,EAEJgB,EAAoB,EAEpB,GAAI,CACFhB,EAAWI,EAAwBW,CAAQ,CAC7C,SACEf,EAAWD,EAAyBC,CAAQ,CAC9C,CAEA,GAAIA,IAAa,OACf,MAAMiB,EAAqBjB,EAAU,0DAA0D,CAEnG,EAEA,OAAO,OAAO,OAAO,CAMnB,OAAK,CACH,GAAI,CAAAU,EAEJ,CAAAA,EAAS,GACTD,EAAUX,EAEV,GAAI,CACFgB,EAAO,CACT,SACET,EAAU,MAAK,CACjB,EACF,EACA,aAAW,CACT,OAAOQ,EAAW,CACpB,EACA,IAAIK,EAAQ,CACVP,EAAU,EAEN,QAAO,GAAGE,EAAW,EAAIK,CAAK,IAElCT,EAAUS,EACVJ,EAAO,EACT,EACA,UAAUR,EAA0B,CAClC,GAAII,EAAQ,OAAOb,EAEnB,MAAMsB,EAAe,CAAE,SAAAb,CAAQ,EAC/BD,EAAU,IAAIc,CAAY,EAC1B,IAAIC,EAAa,GAEjB,MAAO,IAAW,CACXA,IAELA,EAAa,GACbf,EAAU,OAAOc,CAAY,EAC/B,CACF,EACA,OAAOE,EAAyB,CAC9BV,EAAU,EACV,MAAMW,EAAWT,EAAW,EACtBV,EAAOkB,EAAOC,CAAQ,EAG5BX,EAAU,EAEN,QAAO,GAAGW,EAAUnB,CAAI,IAE5BM,EAAUN,EACVW,EAAO,EACT,CACD,CAAA,CACH"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { Readable } from './readable.js';
|
|
2
|
+
/**
|
|
3
|
+
* The async materialization contract. It lives in `core` because `ModelContext.resource` and `ModelContext.stream`
|
|
4
|
+
* name it (D73); `runtime` owns the controllers and the retention policies and re-exports these types unchanged.
|
|
5
|
+
*/
|
|
6
|
+
type ResourceRequestKey = number | string;
|
|
7
|
+
type ResourceIdleSnapshot = {
|
|
8
|
+
readonly attempt: 0;
|
|
9
|
+
readonly data: undefined;
|
|
10
|
+
readonly error: undefined;
|
|
11
|
+
readonly generation: number;
|
|
12
|
+
readonly key: null;
|
|
13
|
+
readonly stale: false;
|
|
14
|
+
readonly status: 'idle';
|
|
15
|
+
};
|
|
16
|
+
type ResourceOpeningSnapshot<Data, Key extends ResourceRequestKey> = {
|
|
17
|
+
readonly attempt: number;
|
|
18
|
+
readonly data: Data | undefined;
|
|
19
|
+
readonly error: undefined;
|
|
20
|
+
readonly generation: number;
|
|
21
|
+
readonly key: Key;
|
|
22
|
+
readonly stale: boolean;
|
|
23
|
+
readonly status: 'opening';
|
|
24
|
+
};
|
|
25
|
+
type ResourceReadySnapshot<Data, Key extends ResourceRequestKey> = {
|
|
26
|
+
readonly attempt: number;
|
|
27
|
+
readonly data: Data;
|
|
28
|
+
readonly error: undefined;
|
|
29
|
+
readonly generation: number;
|
|
30
|
+
readonly key: Key;
|
|
31
|
+
readonly stale: false;
|
|
32
|
+
readonly status: 'ready';
|
|
33
|
+
};
|
|
34
|
+
type ResourceRefreshingSnapshot<Data, Key extends ResourceRequestKey> = {
|
|
35
|
+
readonly attempt: number;
|
|
36
|
+
readonly data: Data;
|
|
37
|
+
readonly error: undefined;
|
|
38
|
+
readonly generation: number;
|
|
39
|
+
readonly key: Key;
|
|
40
|
+
readonly stale: true;
|
|
41
|
+
readonly status: 'refreshing';
|
|
42
|
+
};
|
|
43
|
+
type ResourceErrorSnapshot<Data, Key extends ResourceRequestKey> = {
|
|
44
|
+
readonly attempt: number;
|
|
45
|
+
readonly data: Data | undefined;
|
|
46
|
+
readonly error: unknown;
|
|
47
|
+
readonly generation: number;
|
|
48
|
+
readonly key: Key;
|
|
49
|
+
readonly retryable: true;
|
|
50
|
+
readonly stale: boolean;
|
|
51
|
+
readonly status: 'error';
|
|
52
|
+
};
|
|
53
|
+
type ResourceSnapshot<Data, Key extends ResourceRequestKey = ResourceRequestKey> = ResourceErrorSnapshot<Data, Key> | ResourceIdleSnapshot | ResourceOpeningSnapshot<Data, Key> | ResourceReadySnapshot<Data, Key> | ResourceRefreshingSnapshot<Data, Key>;
|
|
54
|
+
interface Resource<Data, Key extends ResourceRequestKey = ResourceRequestKey> extends Readable<ResourceSnapshot<Data, Key>> {
|
|
55
|
+
readonly invalidate: () => void;
|
|
56
|
+
readonly refresh: () => void;
|
|
57
|
+
readonly retain: () => () => void;
|
|
58
|
+
readonly retry: () => void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* The default retention: a resource lives while somebody observes it, releases after a microtask grace and aborts
|
|
62
|
+
* what is still in flight. Both fields admitted exactly one value each, so the record collapsed to its kind (D160).
|
|
63
|
+
*/
|
|
64
|
+
type ObserverRetention = {
|
|
65
|
+
readonly kind: 'observer';
|
|
66
|
+
};
|
|
67
|
+
type ScopedRetention = {
|
|
68
|
+
readonly capacity: number;
|
|
69
|
+
readonly evict: 'lru';
|
|
70
|
+
readonly kind: 'scope';
|
|
71
|
+
};
|
|
72
|
+
type ResourceRetention = ObserverRetention | ScopedRetention;
|
|
73
|
+
type ResourceRetry = {
|
|
74
|
+
readonly attempts: number;
|
|
75
|
+
readonly delayMs: number;
|
|
76
|
+
};
|
|
77
|
+
type LatestBackpressure = {
|
|
78
|
+
readonly kind: 'latest';
|
|
79
|
+
};
|
|
80
|
+
/** §3 publishes one policy, so the union has one member: `drop`, `sample` and `queue` were unreachable (D160). */
|
|
81
|
+
type StreamBackpressure = LatestBackpressure;
|
|
82
|
+
export type { LatestBackpressure, ObserverRetention, Resource, ResourceRequestKey, ResourceRetention, ResourceRetry, ResourceSnapshot, ScopedRetention, StreamBackpressure, };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type facts every layer needs, declared once. They were re-declared per file — `Awaitable` in nineteen, the
|
|
3
|
+
* exact-input trio in a dozen — and every copy is a second place where the same rule can drift (D150).
|
|
4
|
+
*/
|
|
5
|
+
type Awaitable<Value> = PromiseLike<Value> | Value;
|
|
6
|
+
type IsAny<Value> = 0 extends 1 & Value ? true : false;
|
|
7
|
+
type ExactType<Left, Right> = [Left] extends [Right] ? ([Right] extends [Left] ? true : false) : false;
|
|
8
|
+
/** Author options are exact: an extra key is `never`, so a typo fails where it is written. */
|
|
9
|
+
type NoExtraKeys<Actual, Expected> = Record<Exclude<keyof Actual, keyof Expected>, never>;
|
|
10
|
+
type ExactInput<Actual, Shape> = Actual & NoExtraKeys<Actual, Shape> & Shape;
|
|
11
|
+
type ExactKeys<Keys extends PropertyKey, Shape> = Record<Exclude<Keys, keyof Shape>, never> & Record<Keys, unknown>;
|
|
12
|
+
/** A lifecycle callback publishes nothing: `void` or a promise of it, and `any` is not a way around that. */
|
|
13
|
+
type ExactVoidResult<Value> = IsAny<Value> extends true ? never : [Value] extends [Awaitable<void>] ? unknown : never;
|
|
14
|
+
export type { Awaitable, ExactInput, ExactKeys, ExactType, ExactVoidResult, IsAny, NoExtraKeys };
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opetope/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"engines": {
|
|
5
|
+
"node": ">=20.19.0"
|
|
6
|
+
},
|
|
7
|
+
"browserslist": [
|
|
8
|
+
"Chrome >= 82",
|
|
9
|
+
"Firefox >= 110",
|
|
10
|
+
"Safari >= 15",
|
|
11
|
+
"iOS >= 15",
|
|
12
|
+
"Android >= 82"
|
|
13
|
+
],
|
|
14
|
+
"type": "module",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"README.ru.md",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"CHANGELOG.md"
|
|
21
|
+
],
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./internal": {
|
|
30
|
+
"types": "./dist/internal.d.ts",
|
|
31
|
+
"import": "./dist/internal.js"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"scripts": {
|
|
35
|
+
"build": "rollup --config rollup.config.cjs",
|
|
36
|
+
"build:size-consumers": "rollup --config rollup.size.config.cjs",
|
|
37
|
+
"ci:eslint": "eslint src --quiet",
|
|
38
|
+
"ci:size-limit": "node ../../tooling/typecheck.mjs --noEmit -p tsconfig.size.json && npm run build:size-consumers && size-limit",
|
|
39
|
+
"ci:type": "node ../../tooling/typecheck.mjs --noEmit && node ../../tooling/typecheck.mjs --noEmit -p tsconfig.size.json",
|
|
40
|
+
"ci:test": "node --expose-gc --experimental-vm-modules ../../node_modules/jest/bin/jest.js"
|
|
41
|
+
},
|
|
42
|
+
"size-limit": [
|
|
43
|
+
{
|
|
44
|
+
"name": "author primitives consumer",
|
|
45
|
+
"path": "../../node_modules/.cache/opetope-core-size/author.js",
|
|
46
|
+
"limit": "1.1kb"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"name": "data layer consumer",
|
|
50
|
+
"path": "../../node_modules/.cache/opetope-core-size/data.js",
|
|
51
|
+
"limit": "4.9kb"
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"sideEffects": false,
|
|
55
|
+
"description": "Typed reactive primitives and command execution for Opetope.",
|
|
56
|
+
"license": "MIT",
|
|
57
|
+
"author": "Aleksei Berezin",
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "git+https://github.com/telchardev/opetope.git",
|
|
61
|
+
"directory": "packages/core"
|
|
62
|
+
},
|
|
63
|
+
"publishConfig": {
|
|
64
|
+
"access": "public"
|
|
65
|
+
}
|
|
66
|
+
}
|