@opetope/react 0.10.0 → 0.11.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 CHANGED
@@ -1,5 +1,126 @@
1
1
  # @opetope/react
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 6f23026: **A retirement stops a source, it never breaks it (D364).** `Readable.subscribe` promises «I call you, you read
8
+ me», and `State.close()` was the only operation in the framework that notified and then refused the read. Every
9
+ foreign listener that followed the protocol literally therefore threw, the framework collected that throw into an
10
+ `AggregateError`, and reported it on behalf of a consumer that had done nothing wrong — with a Resource in the
11
+ picture, with a plain `ctx.state` cell and no Resource at all, and across an `optional` weak edge where a consumer
12
+ legitimately outlives its provider. D362 and D363 taught the framework's own nodes to read a close as a lifetime
13
+ fact; neither could reach a listener that is not a framework node.
14
+
15
+ - **The law.** A Resource says `idle('retired')`, a cell keeps its last value, and a read never fails because a
16
+ lifetime ended. `createState.close()` stops accepting writes, lets its listeners go and answers its last value
17
+ for ever; it notifies nobody, because nothing changed, and a later `subscribe` is inert. The controller of a
18
+ Resource publishes one terminal record at its fence and **seals** its publisher behind it, so a retired Resource
19
+ answers that record for as long as a consumer holds it and its controller's publisher retains none of the listener
20
+ closures it handed out. The terminal word belongs to the object whose life ended: a Resource a model owns says
21
+ `retired`, while a feature's `own` or exported Resource is a reference that outlives the instance, so the
22
+ retirement of its controller reaches it as a detachment and it answers `unleased` — one frame, and its verbs
23
+ answer the word its state answers.
24
+ - **One new type name, `ResourceIdleReason`, exported from `@opetope/core` and re-exported by `@opetope/runtime`.**
25
+ The compiler prints `'retired'` to a consumer whose exhaustive branch on `state.reason` breaks, and a union that
26
+ has no name to import is hand-copied instead — which is the one artefact that keeps compiling when a member is
27
+ added. The pagination reasons became one internal type and stay off the public surface.
28
+ - **Two new words, both inhabitants of types that already existed.** `ResourceIdleReason` gains `'retired'` — the
29
+ word the verbs of a retired Resource already answer, which made `state.getSnapshot()` the only member of the
30
+ object that refused the question the rest of it answered. `PaginationState` gains `unavailable('retired')` and
31
+ `PaginationOutcome` `skipped('retired')`: `resource-not-ready` reads as «not yet» and invites a retry loop, and
32
+ `end` would render «everything is loaded» over a Resource that is gone.
33
+ - **`ReadableError` is removed**, with `isClosedReadable`, the followed/unfollowed classification of a committed
34
+ failure, the close branches of `effect`, `scope` and the Resource inputs, the `unreadable` selection decision, both
35
+ catches of the feature `own` facade, and `keepLastOnClose`, the selection's closed-source memory and
36
+ `useResource`'s `lastGoodSnapshot` in `@opetope/react`. A write after the stop raises a `TypeError`; model writes
37
+ are already dropped in silence, so the only reachable caller is a test holding `testReadable`. An exhaustive
38
+ `switch` or a record over `state.reason` breaks at compile time, which is the migration this release asks for.
39
+ - **Inspection.** The frame schema is `opetope.devtools-frame/5`: the `readable` failure subject leaves the union
40
+ with the class that produced it, and the decoder accepts only `/5`. The subscriber count of a Resource is frozen
41
+ when its publisher seals instead of being zeroed, so the row of a fenced materialization reads «fenced, and N
42
+ consumers were still following it».
43
+ - **What did not change.** A producer failure is not a lifetime fact: `resource.state` still refuses a read after
44
+ `publisher.fail` and after a broken `nextCursor`, a `derive` still throws whatever its calculation threw, and
45
+ every such refusal still reaches the reader and is reported once. The weak-edge `Maybe` still says `none` before
46
+ the provider's cells stop, and that is the channel to read.
47
+ - **What it costs.** Stale is quiet where it was loud, and a React reader of `resource.state` renders one more —
48
+ idle — frame while a tree is torn down, where the close used to be swallowed and the last frame stood. A consumer
49
+ that keeps a handle on a stopped cell keeps its last value: measured at 7.99 MB over an 8 MB source, released in
50
+ full when the handle goes, and bounded by the consumer's own reference. A Resource is the opposite: the fence
51
+ releases its `Data`, its cache and its pagination anchor before the terminal record is published, so holding
52
+ `resource.state` for ever costs nothing. The disposer `subscribe` answers is built outside the cell now, so a
53
+ consumer that kept only the disposer — and had therefore let the `Readable` go — no longer pins the last value
54
+ through it.
55
+
56
+ ### Patch Changes
57
+
58
+ - 0eb82ba: **A close is recognized as this source's own, and its memory belongs to the mount (D363).** D362 shipped in 0.10.1
59
+ applied in fewer places than it claimed, and the predicate behind it could not tell three different things apart.
60
+
61
+ - **The scope input of a Resource.** An independent `identity.scope` was read inside the same `try` as
62
+ `resourceKeyOf` and `scopeOf`, so its close became a broken selector: one `ReadableError` in the reporter, and —
63
+ with no materialization current — a published `idle('missing-request')`, which moved the state a close must never
64
+ move. The source is read in its own `try` now; a throwing selector is still `broken`, with one record per
65
+ transition.
66
+ - **`useSelector` with an inline selector.** The memory of «what this reader last read» lived inside a `useMemo`
67
+ whose deps include the selector, so `useReadable` was safe and `useSelector(readable, inline)` — the documented
68
+ form — rebuilt the reader with an empty memory and failed mid-render after a close. The memory of `useSelector`
69
+ and of a `useModel` selection now lives in the ref the mount already holds, so a memo React discarded changes
70
+ nothing.
71
+ - **A source a node never read.** An `effect`, a `scope` or a Resource whose source was already closed when it
72
+ opened swallowed that close: the run never started, no child and no materialization ever opened, and nothing was
73
+ said anywhere. A close with nothing to keep is now reported, as React already did — the law is about not
74
+ reporting the end of work the runtime itself is ending.
75
+ - **A close raised inside a calculation.** A `derive` whose computation reads an unrelated closed `Readable` raised
76
+ a bare close that every observer swallowed, turning a programming fault into silence. Such a failure travels on
77
+ as `A calculation read a closed readable state.` with the close in its `cause`; a close that came out of a source the
78
+ node follows is unchanged.
79
+ - **Two copies of Core.** The predicate was `instanceof`, so a vendored copy beside an installed one raised a close
80
+ that was reported as a foreign failure. It now asks the shape the `Readable` contract already promises — an
81
+ `Error` named `ReadableError` with code `closed` — so the close of either copy is the same fact.
82
+ - **Two React readers that swallowed everything.** `useResource` and the passive reads of a selection caught every
83
+ refusal with a bare `catch`, including a failed publisher cell and a broken `nextCursor`. They apply the same
84
+ predicate now and rethrow anything else.
85
+ - **The selection fast path** records a closed source once instead of re-reading it on every render, so a mount
86
+ whose source closed stops rebuilding its selection — and stops allocating a failure per read — for the rest of
87
+ its life.
88
+
89
+ - Updated dependencies [6f23026]
90
+ - Updated dependencies [0eb82ba]
91
+ - @opetope/core@0.11.0
92
+ - @opetope/runtime@0.11.0
93
+
94
+ ## 0.10.1
95
+
96
+ ### Patch Changes
97
+
98
+ - 5c7abd5: **A closed source says nothing new (D362).** A regression of 0.10.0: any `context.effect` whose source observed
99
+ `resource.state`, directly or through a `derive`, put one `ReadableError: Cannot read a closed readable state.` into
100
+ the model's reporter when the model was fenced. `resource.state` closes inside its controller's fence, while the
101
+ nodes fenced after it still follow it (D338), and a close is a change dependents hear once (D146) — so the `derive`
102
+ recomputed against a closed source and the effect reported that refusal as a failure. The same reached
103
+ `scope.while/switch/keyed` over such a source and the `request`, `enabled` or scope input of another Resource.
104
+
105
+ - **The law.** A runtime node that follows a `Readable` reads a `ReadableError` of code `closed` as a fact about the
106
+ source's lifetime: it keeps what it last observed, does nothing and leaves no reporter record. A `scope` keeps its
107
+ current child, released by its own drain; a Resource keeps the materialization it selected. In React the close
108
+ arrives from outside the model, so `read` in a `useModel` selection, `useSelector` and `useReadable` answer the last
109
+ value they read and a render that raced a retirement shows its last frame instead of failing mid-render, which is
110
+ what `useResource` already did. Unchanged: `resource.state` still closes at retirement, an explicit read by author
111
+ code still fails, and every refusal that is not a close is still reported once.
112
+ - **`Resource.acquire` is a readonly function-valued field**, like `ResourceCommit.update`: the runtime hands out a
113
+ plain function, and it is the one word a consumer holds rather than calls on the spot, so a `useModel` selection may
114
+ name `model.resource.acquire` without tripping `@typescript-eslint/unbound-method` and without a fresh arrow per
115
+ render that would make the selection unequal to itself. The verbs stay methods.
116
+ - **`testResourceEpoch()` on `@opetope/core/testing`** (re-exported by `@opetope/runtime/testing` and
117
+ `@opetope/react/testing`) mints one opaque `ResourceEpoch`, so a test that writes a `ResourceState` by hand no
118
+ longer casts `{} as ResourceEpoch` against the brand.
119
+
120
+ - Updated dependencies [5c7abd5]
121
+ - @opetope/core@0.10.1
122
+ - @opetope/runtime@0.10.1
123
+
3
124
  ## 0.10.0
4
125
 
5
126
  ### Minor Changes
package/README.md CHANGED
@@ -229,9 +229,12 @@ beside it subscribe twice (D349). The compile-checked example of specification
229
229
  it: `inFlight` is true until the outcome of the operation settles, `outcome` carries that `ResourceOperationOutcome`
230
230
  as the `value` of an `ok` status, and `run(undefined, { signal })` cancels the wait of this consumer and not the work
231
231
  the model owns. Two consumers of one Resource keep separate statuses, and `run` keeps its identity while the Resource
232
- does. A render that caught up with retirement answers the last state it saw — what `useReadable` does with a source
233
- its owner closed — and a selection answers a closed record instead of throwing mid-render, so the tree unmounts and
234
- releases its lease rather than breaking the render (D359).
232
+ does. A render that caught up with retirement renders the terminal record — `idle` with reason `retired` for a Resource
233
+ a model owns, `unleased` for a feature's facade, which is a reference that outlives the instance — and unmounts,
234
+ releasing its lease (D359, D364). Nothing here refuses a read because a lifetime ended: a source whose owner retired
235
+ stops and keeps answering its last value, so `useReadable`, `useSelector` with an inline selector and a selection's
236
+ `read` each read on and need no memory of their own. A refusal that remains is work that failed — a state that
237
+ failed, a broken pagination cursor — and it still reaches the render.
235
238
 
236
239
  Direct component props, a contribution's `props` adapter and its model's props `Readable` share the same
237
240
  mount-owned snapshot. Incoming slot props publish in layout before paint, so direct and adapted renders cannot
@@ -292,7 +295,7 @@ a scoped zero-count assertion, without proving absence of arbitrary host, UI or
292
295
  application imports and internal renderer references. A failed cleanup promise can retain original errors and retry
293
296
  capabilities; a caller that keeps `mounted.host` also keeps its own renderer result.
294
297
 
295
- The inspection schemas are `opetope.devtools-graph/5` and `opetope.devtools-frame/4`, with optional
298
+ The inspection schemas are `opetope.devtools-graph/5` and `opetope.devtools-frame/5`, with optional
296
299
  `opetope.runtime-activity/4` snapshots (D266, D275, D344, D358). Within one session,
297
300
  a frame without `activity` preserves the previous activity; a full snapshot/reset without it clears that observation
298
301
  (D216). Activity-bearing frames replace the previous activity in full.
@@ -317,8 +320,9 @@ observation disabled. Graph frames remain bounded by the existing ring capacity.
317
320
  - `renderSlot(target, { contribution, models, props })` mounts the published target or one fixture contribution;
318
321
  - `command(run)` produces an authentic `Call` for a model fixture, plus the contribution binding a mount reads;
319
322
  - `runCall(target, input?, options?)` executes an existing authentic `Call` without mounting React (D261);
320
- - `testReadable(initial)`, `openModel`, `settled`, `waitFor`, `yieldTurn` and `eventually` come from the entries
321
- below, for the part of a test that has no UI in it.
323
+ - `testReadable(initial)`, `testResourceEpoch()`, `openModel`, `settled`, `waitFor`, `yieldTurn` and `eventually`
324
+ come from the entries below, for the part of a test that has no UI in it — `testResourceEpoch()` is what a
325
+ component fixture writing a `ResourceState` by hand puts in its `epoch` (D362).
322
326
 
323
327
  A test that renders nothing should import `@opetope/runtime/testing` directly: `renderSlot` and the binding half of
324
328
  `command` are all that needs React here. The Call a fixture mints is the `command` of `@opetope/core/testing`
package/README.ru.md CHANGED
@@ -228,9 +228,12 @@ render не открывает ничего, а при смене ссылки
228
228
  `inFlight` истинен, пока не осел исход операции, `outcome` несёт этот `ResourceOperationOutcome` значением `value`
229
229
  при статусе `ok`, а `run(undefined, { signal })` отменяет ожидание этого потребителя, а не работу, которой владеет
230
230
  модель. Два потребителя одного Resource держат раздельные статусы, а `run` сохраняет ссылку, пока та же
231
- идентичность Resource. Render, догнавший retirement, отвечает последним виденным состоянием — тем же, что делает
232
- `useReadable` с источником, закрытым его владельцем, — а выборка отвечает закрытой записью вместо падения посреди
233
- render-а, поэтому дерево размонтируется и отпустит аренду, а не сломает рендер (D359).
231
+ идентичность Resource. Render, догнавший retirement, рисует терминальную запись — `idle` с причиной `retired` у Resource, которым
232
+ владеет модель, и `unleased` у фасада фичи, потому что эта ссылка переживает экземпляр, — и размонтируется, отпустив
233
+ аренду (D359, D364). Ничто здесь не отказывает в чтении из-за того, что кончилась чья-то жизнь: источник, у которого
234
+ ушёл владелец, останавливается и продолжает отвечать последним значением, поэтому `useReadable`, `useSelector` с
235
+ inline-селектором и `read` выборки просто читают дальше, и собственная память им не нужна. Оставшийся отказ — это
236
+ упавшая работа: упавшее состояние, сломанный курсор пагинации, — и он по-прежнему доходит до рендера.
234
237
 
235
238
  Прямые пропсы компонента, `props`-адаптер вклада и props-`Readable` его модели используют один снимок
236
239
  монтирования. Входящие пропсы слота публикуются в layout до paint, поэтому прямой и адаптированный рендеры
@@ -292,7 +295,7 @@ Deadline готовности также оставляет приложение
292
295
  host/UI/GC-утечек. Успешный cleanup очищает imports приложения и внутренние ссылки на renderer. Promise отказавшего
293
296
  cleanup может удерживать исходные ошибки и retry capabilities; сохранённый пользователем `mounted.host` удерживает его renderer result.
294
297
 
295
- Inspection использует схемы `opetope.devtools-graph/5` и `opetope.devtools-frame/4`, а также optional snapshots
298
+ Inspection использует схемы `opetope.devtools-graph/5` и `opetope.devtools-frame/5`, а также optional snapshots
296
299
  `opetope.runtime-activity/4` (D266, D275, D344, D358). В пределах одной session
297
300
  frame без `activity` сохраняет предыдущую activity; полный snapshot/reset без этого поля очищает наблюдение (D216).
298
301
  Frame с `activity` заменяет предыдущую activity целиком.
@@ -318,8 +321,9 @@ idle executors могут требовать обхода, чтобы подтв
318
321
  - `renderSlot(target, { contribution, models, props })` монтирует опубликованную цель либо один вклад-фикстуру;
319
322
  - `command(run)` выдаёт подлинный `Call` для фикстуры модели плюс привязку вклада, которую читает монтирование;
320
323
  - `runCall(target, input?, options?)` запускает существующий подлинный `Call` без монтирования React (D261);
321
- - `testReadable(initial)`, `openModel`, `settled`, `waitFor`, `yieldTurn` и `eventually` приходят из входов ниже —
322
- для той части теста, в которой UI нет.
324
+ - `testReadable(initial)`, `testResourceEpoch()`, `openModel`, `settled`, `waitFor`, `yieldTurn` и `eventually`
325
+ приходят из входов ниже — для той части теста, в которой UI нет; `testResourceEpoch()` это то, что фикстура
326
+ компонента, собирающая `ResourceState` руками, кладёт в её `epoch` (D362).
323
327
 
324
328
  Тест, который ничего не рендерит, должен импортировать `@opetope/runtime/testing` напрямую: React здесь нужен
325
329
  только `renderSlot` и привязочной половине `command`. Сам Call фикстуры чеканит `command` из
@@ -1 +1 @@
1
- {"version":3,"file":"contribution-frame-DkNmjChZ.js","sources":["../src/mount-context.tsx","../src/resource-command.ts","../src/readable-hooks.ts","../src/command.ts","../src/model-binding.ts","../src/mount-frame.ts","../src/mount-provider.tsx","../src/contribution-frame.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nimport { ContributionError } from './errors';\nimport type { Frame } from './mount-frame';\n\nconst FrameContext = createContext<Frame | undefined>(undefined);\n\nfunction useFrame(): Frame {\n const frame = useContext(FrameContext);\n\n if (frame === undefined) {\n throw new ContributionError('missing', 'Opetope hook was called outside a contribution mount.');\n }\n\n return frame;\n}\n\nexport { FrameContext, useFrame };\n","/**\n * D359: the verbs of a Resource, dressed as the commands a button already knows, and the recognition that answers\n * «is this selected field a Resource». A consumer keeps a status — `inFlight` until the operation settles, the\n * settled `outcome` — while the Resource stays owned by the model that declared it: cancelling this wait cancels the\n * wait and not the load.\n */\n\nimport { CallError } from '@opetope/core';\nimport type {\n PaginationOutcome,\n PaginationState,\n Resource,\n ResourceOperationOutcome,\n ResourceState,\n} from '@opetope/core';\nimport { compatibleAbortReason, reportDetachedError } from '@opetope/core/internal';\nimport type { CallRunOptions, ResourceKey } from '@opetope/core/internal';\nimport { isResourceValue } from '@opetope/runtime/internal';\n\nimport type { CommandHook } from './command-hook';\nimport type { CommandInvoker } from './command-hook-controller';\n\ntype AnyResource = Resource<never, ResourceKey>;\n\n/**\n * D349, D359: a Resource is a structural contract a host may implement with an ordinary object, so the question the\n * type of a selected field asked is answered by the runtime that owns it — the registry of the materializations it\n * built, and the structural contract for everything else. Asking it here a second time would let the two answers\n * drift, and a host adapter typed as a hook reaches the render where `state` is `undefined` and `refresh.run()`\n * throws.\n */\nfunction isResource(value: unknown): boolean {\n return isResourceValue(value);\n}\n\n/** D356: the nested capability, with `loadNext` as a command and the projected pagination state beside it. */\ntype ResourcePaginationHook<Cursor extends ResourceKey> = Readonly<{\n loadNext: CommandHook<void, PaginationOutcome<Cursor>>;\n state: PaginationState<Cursor>;\n}>;\n\n/**\n * D359: what `useResource` answers, and what a field of a `useModel` selection whose value is a Resource answers.\n * The verbs never reject (a Resource answers an outcome), so the ordinary path of `outcome` is\n * `{ status: 'ok', value }`; `failed` stays in the type because the controller turns a synchronous throw of an\n * invoker into it, and the wrapper below carries its own test that it never throws synchronously.\n */\ntype ResourceHook<Data, Key extends ResourceKey = never> = Readonly<{\n invalidate: CommandHook<void, ResourceOperationOutcome>;\n /** Present when the declaration carried `pagination`; `undefined` for every other Resource. */\n pagination: ResourcePaginationHook<ResourceKey> | undefined;\n refresh: CommandHook<void, ResourceOperationOutcome>;\n retry: CommandHook<void, ResourceOperationOutcome>;\n state: ResourceState<Data, Key>;\n}>;\n\ntype PaginatedResourceHook<Data, Key extends ResourceKey, Cursor extends ResourceKey> = Omit<\n ResourceHook<Data, Key>,\n 'pagination'\n> &\n Readonly<{ pagination: ResourcePaginationHook<Cursor> }>;\n\ntype ResourceInvokers = Readonly<{\n invalidate: CommandInvoker;\n loadNext: CommandInvoker;\n refresh: CommandInvoker;\n retry: CommandInvoker;\n}>;\n\n/** The consumer's own cancellation: it ends this wait, and the work the model owns keeps running. */\nfunction awaitCancellable(operation: Promise<unknown>, signal: AbortSignal): Promise<unknown> {\n return new Promise<unknown>((resolve, reject) => {\n const cancel = (): void => {\n reject(new CallError('cancelled', 'Resource operation wait was cancelled.', compatibleAbortReason(signal)));\n };\n\n if (signal.aborted) {\n cancel();\n\n return;\n }\n\n signal.addEventListener('abort', cancel, { once: true });\n operation.then(\n value => {\n signal.removeEventListener('abort', cancel);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', cancel);\n reject(error);\n },\n );\n });\n}\n\nfunction notifySuccess(value: unknown, options: CallRunOptions<unknown> | undefined): unknown {\n const notification = options?.onSuccess?.(value);\n\n // The failure of a consumer's own callback is detached from the operation it watched, as it is for a command.\n if (notification !== undefined) void Promise.resolve(notification).catch(reportDetachedError);\n\n return value;\n}\n\n/**\n * The invariant of this wrapper: it never throws synchronously, so the `failed` outcome a consumer can see is the one\n * the verb itself produced and never one this layer invented in the middle of a render commit.\n */\nfunction operationInvoker(start: () => Promise<unknown>): CommandInvoker {\n return {\n run: (_input: never, options?: CallRunOptions<unknown>): Promise<unknown> => {\n let operation: Promise<unknown>;\n\n try {\n operation = Promise.resolve(start());\n } catch (error) {\n return Promise.reject(error);\n }\n\n const signal = options?.signal;\n\n return (signal === undefined ? operation : awaitCancellable(operation, signal)).then(value =>\n notifySuccess(value, options),\n );\n },\n };\n}\n\n/** A Resource without the capability still answers a `loadNext` invoker, so the hook count never moves. */\nconst unavailablePage: PaginationOutcome<ResourceKey> = Object.freeze({\n kind: 'skipped',\n reason: 'resource-not-ready',\n});\n\nfunction paginationOf(resource: AnyResource): ResourcePaginationHook<ResourceKey> | undefined {\n const capability = (resource as { readonly pagination?: unknown }).pagination;\n\n if (typeof capability !== 'object' || capability === null) return undefined;\n\n return capability as unknown as ResourcePaginationHook<ResourceKey>;\n}\n\n/**\n * One set per Resource identity. `selectEntry` and `useCommandSlot` both pick their controller by the identity of the\n * invoker, so a set rebuilt on every render would reset `inFlight`, drop `outcome` and change `run` — which is why it\n * is memoised against the Resource itself and never assembled during a render.\n */\nfunction createResourceInvokers(resource: AnyResource): ResourceInvokers {\n // D349: a Resource is a structural contract, so every verb is called through it and never as a detached function.\n return {\n invalidate: operationInvoker(() => resource.invalidate()),\n loadNext: operationInvoker(() => {\n const capability = (resource as { readonly pagination?: { loadNext(): Promise<unknown> } }).pagination;\n\n return capability === undefined ? Promise.resolve(unavailablePage) : capability.loadNext();\n }),\n refresh: operationInvoker(() => resource.refresh()),\n retry: operationInvoker(() => resource.retry()),\n };\n}\n\nfunction resourceInvokers(resource: AnyResource, cache: WeakMap<object, ResourceInvokers>): ResourceInvokers {\n const existing = cache.get(resource);\n\n if (existing !== undefined) return existing;\n\n const invokers = createResourceInvokers(resource);\n cache.set(resource, invokers);\n\n return invokers;\n}\n\n/**\n * The one module of this package that talks to the runtime about a materialization, so the rest of React reads the\n * recognition and the key type from here instead of routing to `@opetope/runtime/internal` of its own.\n */\nexport { createResourceInvokers, isResource, paginationOf, resourceInvokers };\nexport type { AnyResource, PaginatedResourceHook, ResourceHook, ResourceInvokers, ResourceKey, ResourcePaginationHook };\n","import { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\n\nimport type { Readable } from '@opetope/core';\nimport type { EqualityOption } from '@opetope/core/internal';\n\nconst identity = <Value>(value: Value): Value => value;\n\ninterface SelectionInstance<Selected> {\n hasValue: boolean;\n value: Selected | undefined;\n}\n\n/**\n * D279: the source and the selection are positional; `equals` is the one modifier, spelled as in Core — including\n * D348's rule for where the comparator is read, so a named non-generic one compiles here as it does in `derive`.\n */\nexport function useSelector<Value, Selected>(\n readable: Readable<Value>,\n select: (value: NoInfer<Value>) => Selected,\n options?: { readonly equals?: EqualityOption<NoInfer<Selected>> },\n): Selected {\n const selector = select;\n const isEqual = options?.equals ?? Object.is;\n const subscribe = useCallback((listener: () => void) => readable.subscribe(listener), [readable]);\n const instanceRef = useRef<SelectionInstance<Selected> | undefined>(undefined);\n let instance = instanceRef.current;\n\n if (instance === undefined) {\n instance = { hasValue: false, value: undefined };\n instanceRef.current = instance;\n }\n\n const getSelectedSnapshot = useMemo(() => {\n let initialized = false;\n let sourceSnapshot: Value;\n let selectedSnapshot: Selected;\n\n return (): Selected => {\n const nextSource = readable.getSnapshot();\n\n if (initialized && Object.is(sourceSnapshot, nextSource)) return selectedSnapshot;\n\n const nextSelected = selector(nextSource);\n\n if (!initialized) {\n let nextSelectedSnapshot = nextSelected;\n\n if (instance.hasValue && isEqual(instance.value, nextSelected)) {\n nextSelectedSnapshot = instance.value as Selected;\n }\n\n initialized = true;\n sourceSnapshot = nextSource;\n selectedSnapshot = nextSelectedSnapshot;\n\n return selectedSnapshot;\n }\n\n if (isEqual(selectedSnapshot, nextSelected)) {\n sourceSnapshot = nextSource;\n\n return selectedSnapshot;\n }\n\n sourceSnapshot = nextSource;\n selectedSnapshot = nextSelected;\n\n return selectedSnapshot;\n };\n }, [instance, isEqual, readable, selector]);\n\n const selected = useSyncExternalStore(subscribe, getSelectedSnapshot, getSelectedSnapshot);\n\n useEffect(() => {\n instance.hasValue = true;\n instance.value = selected;\n }, [instance, selected]);\n\n return selected;\n}\n\nexport function useReadable<Value>(readable: Readable<Value>): Value {\n return useSelector(readable, identity);\n}\n","import type { Call } from '@opetope/core';\nimport { isCallTarget } from '@opetope/core/internal';\n\nimport { ContributionError } from './errors';\n\n/**\n * A bound command is the authentic `Call` the model field declares, so the common path adds no wrapper. Observable\n * call state belongs to the model as a `Readable` field (D71), so a binding carries no mode.\n */\ntype CommandBindingIdentity = Call<never, unknown>;\ntype CommandBinding<Input, Output> = Call<Input, Output>;\n\ntype CommandOutcome<Output> =\n | { readonly error: unknown; readonly status: 'failed' }\n | { readonly reason: unknown; readonly status: 'cancelled' }\n | { readonly status: 'ok'; readonly value: Output };\n\ntype AnyCommandBinding = CommandBinding<never, unknown>;\n\ntype CommandBindingDefinition<Input, Output> = {\n readonly target: Call<Input, Output>;\n};\n\nconst bindingDefinitions = new WeakMap<CommandBindingIdentity, CommandBindingDefinition<never, unknown>>();\n\nfunction bindCommand<Input, Output>(target: Call<Input, Output>): CommandBinding<Input, Output> {\n if (arguments.length > 1) {\n throw new ContributionError(\n 'binding-invalid',\n 'Command follows the target it binds; binding options are forbidden.',\n );\n }\n\n if (!isCallTarget(target)) throw new ContributionError('binding-invalid', 'Command target is not authentic.');\n\n bindingDefinitions.set(target, { target });\n\n return target;\n}\n\nfunction getCommandBindingDefinition<Input, Output>(\n binding: Call<Input, Output>,\n): CommandBindingDefinition<Input, Output> {\n const definition = bindingDefinitions.get(binding);\n\n if (definition === undefined) throw new ContributionError('binding-invalid', 'Command binding is not authentic.');\n\n return definition as CommandBindingDefinition<Input, Output>;\n}\n\nfunction isCommandBinding(value: unknown): value is AnyCommandBinding {\n return typeof value === 'object' && value !== null && bindingDefinitions.has(value as CommandBindingIdentity);\n}\n\nexport { bindCommand, getCommandBindingDefinition, isCommandBinding };\nexport type { CommandOutcome };\n","import type { Call, ModelOf } from '@opetope/core';\nimport { isModel, isReadable } from '@opetope/core/internal';\nimport type { ModelIdentity, NoExtraKeys } from '@opetope/core/internal';\n\nimport { isCommandBinding } from './command';\nimport { ContributionError } from './errors';\nimport { isResource } from './resource-command';\n\nconst modelBindingBrand = Symbol('opetope.model-binding');\nconst modelBindingIdentityBrand = Symbol('opetope.model-binding-identity');\nconst modelBindingMarker = Object.freeze({});\n\ntype AnyModel = ModelIdentity;\ntype AnyCommand = Call<never, unknown>;\n\ninterface ModelBindingIdentity {\n readonly [modelBindingIdentityBrand]: true;\n}\n\ninterface ModelBinding<Declaration extends AnyModel> extends ModelBindingIdentity {\n readonly [modelBindingBrand]: (declaration: Declaration) => Declaration;\n}\n\ntype ModelBindingMetadata = {\n readonly commands: readonly AnyCommand[];\n readonly declaration: AnyModel;\n readonly model: object;\n};\n\nconst registry = new WeakMap<ModelBindingIdentity, ModelBindingMetadata>();\n\n/**\n * A model field is either a stable Readable or a bound command. The declaration carries the shape in its type, so\n * binding authority is the runtime check that every published field is one of those two authentic kinds.\n */\nfunction modelFieldValue(declaration: AnyModel, model: object, field: PropertyKey): unknown {\n if (typeof field !== 'string') {\n throw new ContributionError('binding-invalid', `Model ${declaration.id} accepts only string fields.`);\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(model, field);\n\n if (descriptor?.enumerable !== true || !('value' in descriptor)) {\n throw new ContributionError(\n 'binding-invalid',\n `Model ${declaration.id}.${field} requires an enumerable data binding.`,\n );\n }\n\n return descriptor.value;\n}\n\nfunction snapshotModelFields(declaration: AnyModel, model: object): readonly AnyCommand[] {\n const commands: AnyCommand[] = [];\n const fields = Reflect.ownKeys(model);\n\n if (fields.length === 0)\n throw new ContributionError('binding-invalid', `Model ${declaration.id} requires at least one field.`);\n\n for (const field of fields) {\n const value = modelFieldValue(declaration, model, field);\n\n // D349: a Resource is a field a model publishes, and it is not a `Readable`, so it is recognised by name.\n if (isReadable(value) || isResource(value) || typeof value === 'function') continue;\n\n if (!isCommandBinding(value)) {\n throw new ContributionError(\n 'binding-invalid',\n `Model ${declaration.id}.${String(field)} requires a Readable, a Resource or a bound command.`,\n );\n }\n\n commands.push(value);\n }\n\n return Object.freeze(commands);\n}\n\nfunction bindModel<Declaration extends AnyModel, const Actual extends ModelOf<Declaration>>(\n declaration: Declaration,\n model: Actual & NoExtraKeys<Actual, ModelOf<Declaration>>,\n): ModelBinding<Declaration> {\n if (!isModel(declaration)) throw new ContributionError('binding-invalid', 'Model declaration is not authentic.');\n\n if (typeof model !== 'object' || model === null) {\n throw new ContributionError('binding-invalid', `Model ${declaration.id} requires a record binding.`);\n }\n\n const commands = snapshotModelFields(declaration, model);\n const binding = Object.freeze({\n [modelBindingBrand]: modelBindingMarker as unknown as (value: Declaration) => Declaration,\n [modelBindingIdentityBrand]: true as const,\n });\n registry.set(binding, { commands, declaration, model });\n\n return binding;\n}\n\nfunction getModelBindingMetadata(binding: ModelBindingIdentity): ModelBindingMetadata {\n const metadata = registry.get(binding);\n\n if (metadata === undefined) throw new ContributionError('binding-invalid', 'Model binding is not authentic.');\n\n return metadata;\n}\n\nexport { bindModel, getModelBindingMetadata };\nexport type { AnyCommand, AnyModel, ModelBindingIdentity };\n","import type {\n CallAuthority,\n CallController,\n CallDiagnostics,\n CallRunOptions,\n LifetimeLease,\n} from '@opetope/core/internal';\nimport { createCallController, createLifetimeController, reportDetachedError } from '@opetope/core/internal';\n\nimport { getCommandBindingDefinition } from './command';\nimport { ContributionError } from './errors';\nimport { getModelBindingMetadata } from './model-binding';\nimport type { AnyCommand, AnyModel, ModelBindingIdentity } from './model-binding';\n\ntype RuntimeCommandInvoker = {\n readonly run: (input: never, options?: CallRunOptions<unknown>) => Promise<unknown>;\n};\n\ntype CommandRecord = {\n readonly controller: CallController<never, unknown>;\n readonly invoker: RuntimeCommandInvoker;\n};\n\n/** What a mounted contribution grants its components: the models it may read and the commands it may invoke. */\ntype Frame = {\n readonly commandRecords: Map<AnyCommand, CommandRecord>;\n readonly models: Map<AnyModel, unknown>;\n};\n\ntype MountFrameLifecycle = {\n readonly isActive: () => boolean;\n readonly onClose: () => void;\n};\n\ntype MountFrameDiagnostics = {\n readonly active: boolean;\n readonly calls: readonly CallDiagnostics[];\n readonly commandRecords: number;\n readonly models: number;\n};\n\nlet nextMountId = 0;\n\nfunction buildFrame(supplied: readonly ModelBindingIdentity[]): {\n readonly commands: readonly AnyCommand[];\n readonly frame: Frame;\n} {\n const models = new Map<AnyModel, unknown>();\n const commands: AnyCommand[] = [];\n const bound = new Set<AnyCommand>();\n\n for (const candidate of supplied) {\n const binding = getModelBindingMetadata(candidate);\n\n if (models.has(binding.declaration)) {\n throw new ContributionError('duplicate', `Model ${binding.declaration.id} is bound twice in one mount.`);\n }\n\n models.set(binding.declaration, binding.model);\n\n for (const command of binding.commands) {\n // D197: one Call is one command of the mount, however many fields of the models name it. A second name is an\n // alias, not a second command, so it shares the record, the activation and the fence.\n if (bound.has(command)) continue;\n\n bound.add(command);\n commands.push(command);\n }\n }\n\n return { commands: Object.freeze(commands), frame: { commandRecords: new Map(), models } };\n}\n\n/**\n * The lifetime of one mounted contribution. `attach` claims it for the renderer, `detach` schedules the close on the\n * next microtask so a StrictMode remount reuses the same mount, and `close` fences every command it granted (D85).\n */\nclass MountFrameImpl {\n readonly frame: Frame;\n private authority: CallAuthority | undefined;\n private boundCommands: readonly AnyCommand[];\n private closeTicket = 0;\n private readonly isActive: (() => boolean) | undefined;\n private readonly lifetime: ReturnType<typeof createLifetimeController>;\n private onClose: (() => void) | undefined;\n private released = false;\n private rendererAttached = false;\n private readonly renderListeners = new Set<{ readonly listener: () => void }>();\n private state: 'active' | 'closed' | 'closing' | 'detached' = 'detached';\n\n constructor(models: readonly ModelBindingIdentity[], lifecycle?: MountFrameLifecycle) {\n const mountId = ++nextMountId;\n this.lifetime = createLifetimeController({ id: `contribution.${String(mountId)}` });\n this.isActive = lifecycle?.isActive;\n this.onClose = lifecycle?.onClose;\n const { commands, frame } = buildFrame(models);\n this.frame = frame;\n this.boundCommands = commands;\n this.buildCommandRecords(mountId);\n }\n\n attach(): boolean {\n if (this.state === 'closing') {\n this.closeTicket += 1;\n this.state = 'active';\n this.rendererAttached = true;\n\n return true;\n }\n\n if (this.state === 'closed') return false;\n\n if (this.state === 'active') throw new ContributionError('duplicate', 'One contribution mount cannot mount twice.');\n\n const authority = this.createAuthority(this.lifetime.open());\n\n try {\n for (const record of this.frame.commandRecords.values()) record.controller.activate();\n } catch (error) {\n this.authority = authority;\n this.state = 'active';\n this.close();\n\n throw error;\n }\n\n this.authority = authority;\n this.rendererAttached = true;\n this.state = 'active';\n\n return true;\n }\n\n close(): void {\n if (this.state === 'closed') return;\n\n this.state = 'closed';\n this.closeTicket += 1;\n this.lifetime.close();\n this.authority = undefined;\n\n for (const record of this.frame.commandRecords.values()) record.controller.close();\n\n const onClose = this.onClose;\n this.onClose = undefined;\n onClose?.();\n this.publishRenderable();\n\n if (!this.rendererAttached) this.releaseFrame();\n }\n\n detach(): void {\n if (!this.rendererAttached) return;\n\n this.rendererAttached = false;\n\n if (this.state === 'closed') {\n this.releaseFrame();\n\n return;\n }\n\n if (this.state !== 'active') return;\n\n this.state = 'closing';\n const ticket = ++this.closeTicket;\n\n queueMicrotask(() => {\n if (this.state === 'closing' && ticket === this.closeTicket) this.close();\n });\n }\n\n diagnostics(): MountFrameDiagnostics {\n const calls = [...this.frame.commandRecords.values()].map(record => record.controller.diagnostics());\n\n return Object.freeze({\n active: this.state === 'active',\n calls: Object.freeze(calls),\n commandRecords: this.frame.commandRecords.size,\n models: this.frame.models.size,\n });\n }\n\n getRenderableSnapshot = (): boolean => this.state !== 'closed' && (this.isActive === undefined || this.isActive());\n\n releaseClosedFrame(): void {\n if (this.state === 'closed') this.releaseFrame();\n }\n\n subscribeRenderable = (listener: () => void): (() => void) => {\n if (this.state === 'closed') return (): void => undefined;\n\n const registration = { listener };\n this.renderListeners.add(registration);\n let subscribed = true;\n\n return (): void => {\n if (!subscribed) return;\n\n subscribed = false;\n this.renderListeners.delete(registration);\n };\n };\n\n private buildCommandRecords(mountId: number): void {\n let commandIndex = 0;\n\n // `buildFrame` already reduced the models to their distinct Calls, so every command here gets its own record.\n for (const command of this.boundCommands) {\n // Authenticity check only: the binding carries no mode since observe was removed (D71).\n getCommandBindingDefinition(command);\n const controller = createCallController(command, {\n captureAuthority: this.captureAuthority,\n id: `contributionCommand.${String(mountId)}.${String(++commandIndex)}`,\n scheduling: { policy: 'parallel' },\n });\n this.frame.commandRecords.set(command, { controller, invoker: Object.freeze({ run: controller.run }) });\n }\n }\n\n private captureAuthority = (): CallAuthority => {\n const authority = this.authority;\n\n if (this.state !== 'active' || authority === undefined) {\n throw new ContributionError('inactive', 'Contribution mount is not active.');\n }\n\n authority.assertCurrent();\n\n return authority;\n };\n\n private createAuthority(lease: LifetimeLease): CallAuthority {\n return Object.freeze({\n assertCurrent: (): void => {\n if (this.state !== 'active') throw new ContributionError('inactive', 'Contribution mount is not active.');\n\n lease.assertCurrent();\n },\n isCurrent: (): boolean => this.state === 'active' && lease.isCurrent(),\n });\n }\n\n private publishRenderable(): void {\n for (const { listener } of [...this.renderListeners]) {\n try {\n listener();\n } catch (error) {\n reportDetachedError(error);\n }\n }\n }\n\n private releaseFrame(): void {\n if (this.released) return;\n\n this.released = true;\n this.frame.commandRecords.clear();\n this.frame.models.clear();\n this.boundCommands = [];\n this.renderListeners.clear();\n }\n}\n\nexport { MountFrameImpl };\nexport type { Frame };\n","import { useInsertionEffect, useLayoutEffect, useSyncExternalStore } from 'react';\nimport type { PropsWithChildren, ReactElement } from 'react';\n\nimport { FrameContext } from './mount-context';\nimport type { MountFrameImpl } from './mount-frame';\n\nfunction MountProvider({\n children,\n mount,\n}: PropsWithChildren<{ readonly mount: MountFrameImpl }>): ReactElement | null {\n const renderable = useSyncExternalStore(\n mount.subscribeRenderable,\n mount.getRenderableSnapshot,\n mount.getRenderableSnapshot,\n );\n\n useInsertionEffect(() => {\n const attached = mount.attach();\n\n if (!attached) return undefined;\n\n return () => mount.detach();\n }, [mount]);\n\n useLayoutEffect(() => {\n if (!renderable) mount.releaseClosedFrame();\n }, [mount, renderable]);\n\n return renderable ? <FrameContext value={mount.frame}>{children}</FrameContext> : null;\n}\n\nexport { MountProvider };\n","import { memo, useCallback, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport type { ComponentType, ReactElement } from 'react';\n\nimport type { DeclarationId, State } from '@opetope/core';\nimport {\n createAggregateError,\n createState,\n getContributionOwner,\n isReadable,\n reportDetachedError,\n} from '@opetope/core/internal';\nimport type { ModelIdentity } from '@opetope/core/internal';\nimport { openContributionModels, reportRuntimeFailure, requireContributionModelPlans } from '@opetope/runtime/internal';\nimport type { ContributionModelBundle, RuntimeErrorReporter } from '@opetope/runtime/internal';\n\nimport { bindCommand, isCommandBinding } from './command';\nimport { ContributionIsolation, useContributionErrorContent } from './contribution-isolation';\nimport { bindModel } from './model-binding';\nimport { isResource } from './resource-command';\nimport type { ModelBindingIdentity } from './model-binding';\nimport { MountFrameImpl } from './mount-frame';\nimport { MountProvider } from './mount-provider';\nimport { useReadable } from './readable-hooks';\n\ntype AnyModel = ModelIdentity;\ntype ContributionAuthority = {\n /** The feature whose generation published this contribution (D257). */\n readonly feature?: DeclarationId;\n readonly models: readonly (readonly [AnyModel, unknown])[];\n /** The reporter of the feature that published this contribution: a contained failure is its diagnostic, not ours. */\n readonly reporter?: RuntimeErrorReporter;\n};\ntype ModelFixture = readonly [declaration: AnyModel, model: unknown];\n\ntype ContributionValue = {\n readonly Component: ComponentType<never>;\n readonly models?: readonly object[] | undefined;\n readonly props?: ((slotProps: never) => object) | undefined;\n};\n\ntype ContributionMountProps = {\n readonly authority?: ContributionAuthority | undefined;\n readonly contribution: ContributionValue;\n /** The published entry this mount renders, and the slot it renders in: the identity of a contained failure (D257). */\n readonly contributionId: DeclarationId;\n readonly fixtures?: readonly ModelFixture[];\n readonly slotProps: object;\n readonly targetId: DeclarationId;\n};\n\ntype MountBundle = {\n readonly frame: MountFrameImpl;\n readonly isOpen: () => boolean;\n readonly props: State<object>;\n};\n\ntype MountOwner = {\n readonly authority: ContributionAuthority | undefined;\n bundle: MountBundle | undefined;\n readonly contribution: ContributionValue;\n readonly fixtures: readonly ModelFixture[] | undefined;\n retired: boolean;\n};\n\ntype CommittedMount = {\n readonly bundle: MountBundle;\n readonly owner: MountOwner;\n};\n\nfunction closeOwnedMount(owner: MountOwner): void {\n const bundle = owner.bundle;\n owner.bundle = undefined;\n bundle?.frame.close();\n}\n\n/**\n * Model fields arrive as authentic kernel calls; binding them registers the command records the frame needs. D349: a\n * Resource is none of those and needs none of it — it is a field the selection reads on its own terms, so it travels\n * to the frame unchanged instead of being offered to `bindCommand`, which would refuse it as inauthentic.\n */\nfunction bindFrameModel(declaration: AnyModel, model: unknown): ModelBindingIdentity {\n if (typeof model !== 'object' || model === null) return bindModel(declaration as never, model as never);\n\n const passesThrough = (value: unknown): boolean =>\n isReadable(value) || isResource(value) || typeof value === 'function' || isCommandBinding(value);\n const fields = Object.entries(model).map(([key, value]): readonly [string, unknown] => [\n key,\n passesThrough(value) ? value : bindCommand(value as never),\n ]);\n\n return bindModel(declaration as never, Object.fromEntries(fields) as never);\n}\n\n/**\n * D70: the authority of a contribution belongs to the entry a feature published, not to the value it wrote. One\n * static contribution object may be published by two features, and each mount must read the models of its own.\n */\nfunction contributionAuthority(entry: unknown): ContributionAuthority | undefined {\n return getContributionOwner(entry) as ContributionAuthority | undefined;\n}\n\n/** A mount with no publishing generation behind it: a fixture of a component test grants nothing and reports nowhere. */\nconst unownedContribution: ContributionAuthority = { models: [] };\n\nfunction cleanupFailedMount(close: () => void, cause: unknown): never {\n try {\n close();\n } catch (error) {\n throw createAggregateError([cause, error], 'Contribution mount setup and cleanup failed.', { cause });\n }\n\n throw cause;\n}\n\nfunction contributionModels(\n contribution: ContributionValue,\n slotProps: object,\n fixtures: readonly ModelFixture[],\n owner: ContributionAuthority | undefined,\n): {\n readonly bundle: ContributionModelBundle | undefined;\n readonly models: readonly ModelFixture[];\n readonly props: State<object>;\n} {\n const props = createState(slotProps);\n const { models: granted, reporter } = owner ?? unownedContribution;\n\n try {\n const plans = requireContributionModelPlans(contribution.models);\n const bundle = plans.length === 0 ? undefined : openContributionModels(plans, props, reporter);\n\n return {\n bundle,\n models: [...granted, ...(bundle?.models ?? []), ...fixtures],\n props,\n };\n } catch (error) {\n return cleanupFailedMount(props.close, error);\n }\n}\n\nfunction createMountBundle(\n contribution: ContributionValue,\n slotProps: object,\n fixtures: readonly ModelFixture[],\n authority: ContributionAuthority | undefined,\n): MountBundle {\n const { bundle, models, props } = contributionModels(contribution, slotProps, fixtures, authority);\n let closed = false;\n const close = (): void => {\n if (closed) return;\n\n closed = true;\n\n try {\n void bundle?.close().catch(reportDetachedError);\n } finally {\n props.close();\n }\n };\n try {\n const frame = new MountFrameImpl(\n models.map(([declaration, model]) => bindFrameModel(declaration, model)),\n { isActive: () => !closed, onClose: close },\n );\n\n return { frame, isOpen: () => !closed, props };\n } catch (error) {\n return cleanupFailedMount(close, error);\n }\n}\n\nfunction createComponentElement(Component: ComponentType<never>, props: object): ReactElement {\n const Rendered = Component as ComponentType<object>;\n\n return <Rendered {...props} />;\n}\n\ntype MountedContributionProps = {\n readonly bundle: MountBundle;\n readonly contribution: ContributionValue;\n};\n\n/** Reads the committed props of one live mount: every hook here sees a bundle that already exists. */\nfunction MountedContribution({ bundle, contribution }: MountedContributionProps): ReactElement {\n const committedProps = useReadable(bundle.props);\n const componentProps = useMemo(\n () => (contribution.props === undefined ? committedProps : contribution.props(committedProps as never)),\n [committedProps, contribution],\n );\n\n return (\n <MountProvider mount={bundle.frame}>{createComponentElement(contribution.Component, componentProps)}</MountProvider>\n );\n}\n\n/**\n * D188: a mount is created in commit, never in render. The first pass renders nothing, the layout effect builds the\n * bundle from the props that committed and publishes it, and React flushes that update before paint. A render that\n * is thrown away — StrictMode's double invoke, an abandoned concurrent pass, a suspended sibling — therefore\n * creates no models at all, so there is nothing to sweep, adopt or replace.\n */\nfunction ContributionMount({\n authority,\n contribution,\n fixtures,\n slotProps,\n}: ContributionMountProps): ReactElement | null {\n const owner = useMemo<MountOwner>(\n () => ({ authority, bundle: undefined, contribution, fixtures, retired: false }),\n [authority, contribution, fixtures],\n );\n const [committed, setCommitted] = useState<CommittedMount | undefined>(undefined);\n const bundle = committed?.owner === owner ? committed.bundle : undefined;\n const committedSlotProps = useRef(slotProps);\n\n useLayoutEffect(() => {\n committedSlotProps.current = slotProps;\n });\n\n // Suspense disconnects layout effects while hiding, but insertion cleanup only retires an actual identity.\n // Do not close Readables in insertion: their listeners may update React. A hidden tree has no layout cleanup\n // left to run on unmount, so the microtask also releases a mount that never becomes visible again.\n useInsertionEffect(\n () => () => {\n owner.retired = true;\n queueMicrotask(() => {\n try {\n closeOwnedMount(owner);\n } catch (error) {\n reportDetachedError(error);\n }\n });\n },\n [owner],\n );\n\n // The identity of the contribution owns the mount; a reveal and StrictMode reuse what its first commit created.\n useLayoutEffect(() => {\n const created = (owner.bundle ??= createMountBundle(\n owner.contribution,\n committedSlotProps.current,\n owner.fixtures ?? [],\n owner.authority,\n ));\n setCommitted(current => (current?.owner === owner ? current : { bundle: created, owner }));\n\n return () => {\n if (owner.retired) closeOwnedMount(owner);\n };\n }, [owner]);\n\n // Both the component and its models read the same committed snapshot, published before paint.\n useLayoutEffect(() => {\n if (bundle?.isOpen() === true) bundle.props.set(slotProps);\n }, [bundle, slotProps]);\n\n if (bundle === undefined) return null;\n\n return <MountedContribution bundle={bundle} contribution={contribution} />;\n}\n\n/**\n * D256: every mount is a boundary. The isolation sits above `ContributionMount`, so it contains the render of the\n * component and the commit that builds the mount alike, and a retry rebuilds the mount instead of reusing the bundle\n * that failed. Containment is unconditional; the content a failure shows is the host policy of `ContributionBoundary`.\n */\nfunction IsolatedContributionMount(props: ContributionMountProps): ReactElement {\n const { authority, contribution, contributionId, fixtures, targetId } = props;\n const content = useContributionErrorContent();\n const identity = useMemo(() => ({ authority, contribution, fixtures }), [authority, contribution, fixtures]);\n const feature = authority?.feature;\n const source = useMemo(\n () => ({ contribution: contributionId, feature, target: targetId }),\n [contributionId, feature, targetId],\n );\n const reporter = authority?.reporter;\n const report = useCallback((error: unknown) => reportRuntimeFailure(error, reporter), [reporter]);\n\n return (\n <ContributionIsolation content={content} identity={identity} report={report} source={source}>\n <ContributionMount {...props} />\n </ContributionIsolation>\n );\n}\n\n/**\n * One mount, one memo: `Slot` recreates its children whenever `entries` changes, so publishing or withholding one\n * contribution used to re-render every other mount of that target. The props are the contribution, the slot props\n * and the fixtures, all of which are stable while nothing about that mount changed.\n */\nconst MemoizedContributionMount = memo(IsolatedContributionMount);\n\nexport { contributionAuthority, MemoizedContributionMount as ContributionMount };\nexport type { ContributionValue, ModelFixture };\n"],"names":["FrameContext","createContext","useFrame","frame","useContext","ContributionError","isResource","value","isResourceValue","awaitCancellable","operation","signal","resolve","reject","cancel","CallError","compatibleAbortReason","error","notifySuccess","options","notification","_a","reportDetachedError","operationInvoker","start","_input","unavailablePage","paginationOf","resource","capability","createResourceInvokers","resourceInvokers","cache","existing","invokers","identity","useSelector","readable","select","selector","isEqual","subscribe","useCallback","listener","instanceRef","useRef","instance","getSelectedSnapshot","useMemo","initialized","sourceSnapshot","selectedSnapshot","nextSource","nextSelected","nextSelectedSnapshot","selected","useSyncExternalStore","useEffect","useReadable","bindingDefinitions","bindCommand","target","isCallTarget","getCommandBindingDefinition","binding","definition","isCommandBinding","modelBindingBrand","modelBindingIdentityBrand","modelBindingMarker","registry","modelFieldValue","declaration","model","field","descriptor","snapshotModelFields","commands","fields","isReadable","bindModel","isModel","getModelBindingMetadata","metadata","nextMountId","buildFrame","supplied","models","bound","candidate","command","MountFrameImpl","lifecycle","mountId","createLifetimeController","authority","record","onClose","ticket","calls","registration","subscribed","commandIndex","controller","createCallController","lease","MountProvider","children","mount","renderable","useInsertionEffect","useLayoutEffect","_jsx","closeOwnedMount","owner","bundle","bindFrameModel","passesThrough","key","contributionAuthority","entry","getContributionOwner","unownedContribution","cleanupFailedMount","close","cause","createAggregateError","contributionModels","contribution","slotProps","fixtures","props","createState","granted","reporter","plans","requireContributionModelPlans","openContributionModels","createMountBundle","closed","createComponentElement","Component","MountedContribution","committedProps","componentProps","ContributionMount","committed","setCommitted","useState","committedSlotProps","created","current","IsolatedContributionMount","contributionId","targetId","content","useContributionErrorContent","feature","source","report","reportRuntimeFailure","ContributionIsolation","MemoizedContributionMount","memo"],"mappings":"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"}
1
+ {"version":3,"file":"contribution-frame-DkNmjChZ.js","sources":["../src/mount-context.tsx","../src/resource-command.ts","../src/readable-hooks.ts","../src/command.ts","../src/model-binding.ts","../src/mount-frame.ts","../src/mount-provider.tsx","../src/contribution-frame.tsx"],"sourcesContent":["import { createContext, useContext } from 'react';\n\nimport { ContributionError } from './errors';\nimport type { Frame } from './mount-frame';\n\nconst FrameContext = createContext<Frame | undefined>(undefined);\n\nfunction useFrame(): Frame {\n const frame = useContext(FrameContext);\n\n if (frame === undefined) {\n throw new ContributionError('missing', 'Opetope hook was called outside a contribution mount.');\n }\n\n return frame;\n}\n\nexport { FrameContext, useFrame };\n","/**\n * D359: the verbs of a Resource, dressed as the commands a button already knows, and the recognition that answers\n * «is this selected field a Resource». A consumer keeps a status — `inFlight` until the operation settles, the\n * settled `outcome` — while the Resource stays owned by the model that declared it: cancelling this wait cancels the\n * wait and not the load.\n */\n\nimport { CallError } from '@opetope/core';\nimport type {\n PaginationOutcome,\n PaginationState,\n Resource,\n ResourceOperationOutcome,\n ResourceState,\n} from '@opetope/core';\nimport { compatibleAbortReason, reportDetachedError } from '@opetope/core/internal';\nimport type { CallRunOptions, ResourceKey } from '@opetope/core/internal';\nimport { isResourceValue } from '@opetope/runtime/internal';\n\nimport type { CommandHook } from './command-hook';\nimport type { CommandInvoker } from './command-hook-controller';\n\ntype AnyResource = Resource<never, ResourceKey>;\n\n/**\n * D349, D359: a Resource is a structural contract a host may implement with an ordinary object, so the question the\n * type of a selected field asked is answered by the runtime that owns it — the registry of the materializations it\n * built, and the structural contract for everything else. Asking it here a second time would let the two answers\n * drift, and a host adapter typed as a hook reaches the render where `state` is `undefined` and `refresh.run()`\n * throws.\n */\nfunction isResource(value: unknown): boolean {\n return isResourceValue(value);\n}\n\n/** D356: the nested capability, with `loadNext` as a command and the projected pagination state beside it. */\ntype ResourcePaginationHook<Cursor extends ResourceKey> = Readonly<{\n loadNext: CommandHook<void, PaginationOutcome<Cursor>>;\n state: PaginationState<Cursor>;\n}>;\n\n/**\n * D359: what `useResource` answers, and what a field of a `useModel` selection whose value is a Resource answers.\n * The verbs never reject (a Resource answers an outcome), so the ordinary path of `outcome` is\n * `{ status: 'ok', value }`; `failed` stays in the type because the controller turns a synchronous throw of an\n * invoker into it, and the wrapper below carries its own test that it never throws synchronously.\n */\ntype ResourceHook<Data, Key extends ResourceKey = never> = Readonly<{\n invalidate: CommandHook<void, ResourceOperationOutcome>;\n /** Present when the declaration carried `pagination`; `undefined` for every other Resource. */\n pagination: ResourcePaginationHook<ResourceKey> | undefined;\n refresh: CommandHook<void, ResourceOperationOutcome>;\n retry: CommandHook<void, ResourceOperationOutcome>;\n state: ResourceState<Data, Key>;\n}>;\n\ntype PaginatedResourceHook<Data, Key extends ResourceKey, Cursor extends ResourceKey> = Omit<\n ResourceHook<Data, Key>,\n 'pagination'\n> &\n Readonly<{ pagination: ResourcePaginationHook<Cursor> }>;\n\ntype ResourceInvokers = Readonly<{\n invalidate: CommandInvoker;\n loadNext: CommandInvoker;\n refresh: CommandInvoker;\n retry: CommandInvoker;\n}>;\n\n/** The consumer's own cancellation: it ends this wait, and the work the model owns keeps running. */\nfunction awaitCancellable(operation: Promise<unknown>, signal: AbortSignal): Promise<unknown> {\n return new Promise<unknown>((resolve, reject) => {\n const cancel = (): void => {\n reject(new CallError('cancelled', 'Resource operation wait was cancelled.', compatibleAbortReason(signal)));\n };\n\n if (signal.aborted) {\n cancel();\n\n return;\n }\n\n signal.addEventListener('abort', cancel, { once: true });\n operation.then(\n value => {\n signal.removeEventListener('abort', cancel);\n resolve(value);\n },\n (error: unknown) => {\n signal.removeEventListener('abort', cancel);\n reject(error);\n },\n );\n });\n}\n\nfunction notifySuccess(value: unknown, options: CallRunOptions<unknown> | undefined): unknown {\n const notification = options?.onSuccess?.(value);\n\n // The failure of a consumer's own callback is detached from the operation it watched, as it is for a command.\n if (notification !== undefined) void Promise.resolve(notification).catch(reportDetachedError);\n\n return value;\n}\n\n/**\n * The invariant of this wrapper: it never throws synchronously, so the `failed` outcome a consumer can see is the one\n * the verb itself produced and never one this layer invented in the middle of a render commit.\n */\nfunction operationInvoker(start: () => Promise<unknown>): CommandInvoker {\n return {\n run: (_input: never, options?: CallRunOptions<unknown>): Promise<unknown> => {\n let operation: Promise<unknown>;\n\n try {\n operation = Promise.resolve(start());\n } catch (error) {\n return Promise.reject(error);\n }\n\n const signal = options?.signal;\n\n return (signal === undefined ? operation : awaitCancellable(operation, signal)).then(value =>\n notifySuccess(value, options),\n );\n },\n };\n}\n\n/** A Resource without the capability still answers a `loadNext` invoker, so the hook count never moves. */\nconst unavailablePage: PaginationOutcome<ResourceKey> = Object.freeze({\n kind: 'skipped',\n reason: 'resource-not-ready',\n});\n\nfunction paginationOf(resource: AnyResource): ResourcePaginationHook<ResourceKey> | undefined {\n const capability = (resource as { readonly pagination?: unknown }).pagination;\n\n if (typeof capability !== 'object' || capability === null) return undefined;\n\n return capability as unknown as ResourcePaginationHook<ResourceKey>;\n}\n\n/**\n * One set per Resource identity. `selectEntry` and `useCommandSlot` both pick their controller by the identity of the\n * invoker, so a set rebuilt on every render would reset `inFlight`, drop `outcome` and change `run` — which is why it\n * is memoised against the Resource itself and never assembled during a render.\n */\nfunction createResourceInvokers(resource: AnyResource): ResourceInvokers {\n // D349: a Resource is a structural contract, so every verb is called through it and never as a detached function.\n return {\n invalidate: operationInvoker(() => resource.invalidate()),\n loadNext: operationInvoker(() => {\n const capability = (resource as { readonly pagination?: { loadNext(): Promise<unknown> } }).pagination;\n\n return capability === undefined ? Promise.resolve(unavailablePage) : capability.loadNext();\n }),\n refresh: operationInvoker(() => resource.refresh()),\n retry: operationInvoker(() => resource.retry()),\n };\n}\n\nfunction resourceInvokers(resource: AnyResource, cache: WeakMap<object, ResourceInvokers>): ResourceInvokers {\n const existing = cache.get(resource);\n\n if (existing !== undefined) return existing;\n\n const invokers = createResourceInvokers(resource);\n cache.set(resource, invokers);\n\n return invokers;\n}\n\n/**\n * The one module of this package that talks to the runtime about a materialization, so the rest of React reads the\n * recognition and the key type from here instead of routing to `@opetope/runtime/internal` of its own.\n */\nexport { createResourceInvokers, isResource, paginationOf, resourceInvokers };\nexport type { AnyResource, PaginatedResourceHook, ResourceHook, ResourceInvokers, ResourceKey, ResourcePaginationHook };\n","import { useCallback, useEffect, useMemo, useRef, useSyncExternalStore } from 'react';\n\nimport type { Readable } from '@opetope/core';\nimport type { EqualityOption } from '@opetope/core/internal';\n\nconst identity = <Value>(value: Value): Value => value;\n\n/**\n * D364: what this mount answered last, and nothing about closes. A source whose owner retired stops instead of\n * refusing — it keeps answering its last value — so a render that races a retirement shows its last frame and\n * unmounts (G13) without the reader having to remember anything for it.\n */\ninterface SelectionInstance<Selected> {\n hasValue: boolean;\n value: Selected | undefined;\n}\n\n/**\n * D279: the source and the selection are positional; `equals` is the one modifier, spelled as in Core — including\n * D348's rule for where the comparator is read, so a named non-generic one compiles here as it does in `derive`.\n */\nexport function useSelector<Value, Selected>(\n readable: Readable<Value>,\n select: (value: NoInfer<Value>) => Selected,\n options?: { readonly equals?: EqualityOption<NoInfer<Selected>> },\n): Selected {\n const selector = select;\n const isEqual = options?.equals ?? Object.is;\n const subscribe = useCallback((listener: () => void) => readable.subscribe(listener), [readable]);\n const instanceRef = useRef<SelectionInstance<Selected> | undefined>(undefined);\n let instance = instanceRef.current;\n\n if (instance === undefined) {\n instance = { hasValue: false, value: undefined };\n instanceRef.current = instance;\n }\n\n const getSelectedSnapshot = useMemo(() => {\n let initialized = false;\n let sourceSnapshot: Value;\n let selectedSnapshot: Selected;\n\n return (): Selected => {\n const nextSource = readable.getSnapshot();\n\n if (initialized && Object.is(sourceSnapshot, nextSource)) return selectedSnapshot;\n\n const nextSelected = selector(nextSource);\n\n if (!initialized) {\n let nextSelectedSnapshot = nextSelected;\n\n if (instance.hasValue && isEqual(instance.value, nextSelected)) {\n nextSelectedSnapshot = instance.value as Selected;\n }\n\n initialized = true;\n sourceSnapshot = nextSource;\n selectedSnapshot = nextSelectedSnapshot;\n\n return selectedSnapshot;\n }\n\n if (isEqual(selectedSnapshot, nextSelected)) {\n sourceSnapshot = nextSource;\n\n return selectedSnapshot;\n }\n\n sourceSnapshot = nextSource;\n selectedSnapshot = nextSelected;\n\n return selectedSnapshot;\n };\n }, [instance, isEqual, readable, selector]);\n\n const selected = useSyncExternalStore(subscribe, getSelectedSnapshot, getSelectedSnapshot);\n\n useEffect(() => {\n instance.hasValue = true;\n instance.value = selected;\n }, [instance, selected]);\n\n return selected;\n}\n\nexport function useReadable<Value>(readable: Readable<Value>): Value {\n return useSelector(readable, identity);\n}\n","import type { Call } from '@opetope/core';\nimport { isCallTarget } from '@opetope/core/internal';\n\nimport { ContributionError } from './errors';\n\n/**\n * A bound command is the authentic `Call` the model field declares, so the common path adds no wrapper. Observable\n * call state belongs to the model as a `Readable` field (D71), so a binding carries no mode.\n */\ntype CommandBindingIdentity = Call<never, unknown>;\ntype CommandBinding<Input, Output> = Call<Input, Output>;\n\ntype CommandOutcome<Output> =\n | { readonly error: unknown; readonly status: 'failed' }\n | { readonly reason: unknown; readonly status: 'cancelled' }\n | { readonly status: 'ok'; readonly value: Output };\n\ntype AnyCommandBinding = CommandBinding<never, unknown>;\n\ntype CommandBindingDefinition<Input, Output> = {\n readonly target: Call<Input, Output>;\n};\n\nconst bindingDefinitions = new WeakMap<CommandBindingIdentity, CommandBindingDefinition<never, unknown>>();\n\nfunction bindCommand<Input, Output>(target: Call<Input, Output>): CommandBinding<Input, Output> {\n if (arguments.length > 1) {\n throw new ContributionError(\n 'binding-invalid',\n 'Command follows the target it binds; binding options are forbidden.',\n );\n }\n\n if (!isCallTarget(target)) throw new ContributionError('binding-invalid', 'Command target is not authentic.');\n\n bindingDefinitions.set(target, { target });\n\n return target;\n}\n\nfunction getCommandBindingDefinition<Input, Output>(\n binding: Call<Input, Output>,\n): CommandBindingDefinition<Input, Output> {\n const definition = bindingDefinitions.get(binding);\n\n if (definition === undefined) throw new ContributionError('binding-invalid', 'Command binding is not authentic.');\n\n return definition as CommandBindingDefinition<Input, Output>;\n}\n\nfunction isCommandBinding(value: unknown): value is AnyCommandBinding {\n return typeof value === 'object' && value !== null && bindingDefinitions.has(value as CommandBindingIdentity);\n}\n\nexport { bindCommand, getCommandBindingDefinition, isCommandBinding };\nexport type { CommandOutcome };\n","import type { Call, ModelOf } from '@opetope/core';\nimport { isModel, isReadable } from '@opetope/core/internal';\nimport type { ModelIdentity, NoExtraKeys } from '@opetope/core/internal';\n\nimport { isCommandBinding } from './command';\nimport { ContributionError } from './errors';\nimport { isResource } from './resource-command';\n\nconst modelBindingBrand = Symbol('opetope.model-binding');\nconst modelBindingIdentityBrand = Symbol('opetope.model-binding-identity');\nconst modelBindingMarker = Object.freeze({});\n\ntype AnyModel = ModelIdentity;\ntype AnyCommand = Call<never, unknown>;\n\ninterface ModelBindingIdentity {\n readonly [modelBindingIdentityBrand]: true;\n}\n\ninterface ModelBinding<Declaration extends AnyModel> extends ModelBindingIdentity {\n readonly [modelBindingBrand]: (declaration: Declaration) => Declaration;\n}\n\ntype ModelBindingMetadata = {\n readonly commands: readonly AnyCommand[];\n readonly declaration: AnyModel;\n readonly model: object;\n};\n\nconst registry = new WeakMap<ModelBindingIdentity, ModelBindingMetadata>();\n\n/**\n * A model field is either a stable Readable or a bound command. The declaration carries the shape in its type, so\n * binding authority is the runtime check that every published field is one of those two authentic kinds.\n */\nfunction modelFieldValue(declaration: AnyModel, model: object, field: PropertyKey): unknown {\n if (typeof field !== 'string') {\n throw new ContributionError('binding-invalid', `Model ${declaration.id} accepts only string fields.`);\n }\n\n const descriptor = Object.getOwnPropertyDescriptor(model, field);\n\n if (descriptor?.enumerable !== true || !('value' in descriptor)) {\n throw new ContributionError(\n 'binding-invalid',\n `Model ${declaration.id}.${field} requires an enumerable data binding.`,\n );\n }\n\n return descriptor.value;\n}\n\nfunction snapshotModelFields(declaration: AnyModel, model: object): readonly AnyCommand[] {\n const commands: AnyCommand[] = [];\n const fields = Reflect.ownKeys(model);\n\n if (fields.length === 0)\n throw new ContributionError('binding-invalid', `Model ${declaration.id} requires at least one field.`);\n\n for (const field of fields) {\n const value = modelFieldValue(declaration, model, field);\n\n // D349: a Resource is a field a model publishes, and it is not a `Readable`, so it is recognised by name.\n if (isReadable(value) || isResource(value) || typeof value === 'function') continue;\n\n if (!isCommandBinding(value)) {\n throw new ContributionError(\n 'binding-invalid',\n `Model ${declaration.id}.${String(field)} requires a Readable, a Resource or a bound command.`,\n );\n }\n\n commands.push(value);\n }\n\n return Object.freeze(commands);\n}\n\nfunction bindModel<Declaration extends AnyModel, const Actual extends ModelOf<Declaration>>(\n declaration: Declaration,\n model: Actual & NoExtraKeys<Actual, ModelOf<Declaration>>,\n): ModelBinding<Declaration> {\n if (!isModel(declaration)) throw new ContributionError('binding-invalid', 'Model declaration is not authentic.');\n\n if (typeof model !== 'object' || model === null) {\n throw new ContributionError('binding-invalid', `Model ${declaration.id} requires a record binding.`);\n }\n\n const commands = snapshotModelFields(declaration, model);\n const binding = Object.freeze({\n [modelBindingBrand]: modelBindingMarker as unknown as (value: Declaration) => Declaration,\n [modelBindingIdentityBrand]: true as const,\n });\n registry.set(binding, { commands, declaration, model });\n\n return binding;\n}\n\nfunction getModelBindingMetadata(binding: ModelBindingIdentity): ModelBindingMetadata {\n const metadata = registry.get(binding);\n\n if (metadata === undefined) throw new ContributionError('binding-invalid', 'Model binding is not authentic.');\n\n return metadata;\n}\n\nexport { bindModel, getModelBindingMetadata };\nexport type { AnyCommand, AnyModel, ModelBindingIdentity };\n","import type {\n CallAuthority,\n CallController,\n CallDiagnostics,\n CallRunOptions,\n LifetimeLease,\n} from '@opetope/core/internal';\nimport { createCallController, createLifetimeController, reportDetachedError } from '@opetope/core/internal';\n\nimport { getCommandBindingDefinition } from './command';\nimport { ContributionError } from './errors';\nimport { getModelBindingMetadata } from './model-binding';\nimport type { AnyCommand, AnyModel, ModelBindingIdentity } from './model-binding';\n\ntype RuntimeCommandInvoker = {\n readonly run: (input: never, options?: CallRunOptions<unknown>) => Promise<unknown>;\n};\n\ntype CommandRecord = {\n readonly controller: CallController<never, unknown>;\n readonly invoker: RuntimeCommandInvoker;\n};\n\n/** What a mounted contribution grants its components: the models it may read and the commands it may invoke. */\ntype Frame = {\n readonly commandRecords: Map<AnyCommand, CommandRecord>;\n readonly models: Map<AnyModel, unknown>;\n};\n\ntype MountFrameLifecycle = {\n readonly isActive: () => boolean;\n readonly onClose: () => void;\n};\n\ntype MountFrameDiagnostics = {\n readonly active: boolean;\n readonly calls: readonly CallDiagnostics[];\n readonly commandRecords: number;\n readonly models: number;\n};\n\nlet nextMountId = 0;\n\nfunction buildFrame(supplied: readonly ModelBindingIdentity[]): {\n readonly commands: readonly AnyCommand[];\n readonly frame: Frame;\n} {\n const models = new Map<AnyModel, unknown>();\n const commands: AnyCommand[] = [];\n const bound = new Set<AnyCommand>();\n\n for (const candidate of supplied) {\n const binding = getModelBindingMetadata(candidate);\n\n if (models.has(binding.declaration)) {\n throw new ContributionError('duplicate', `Model ${binding.declaration.id} is bound twice in one mount.`);\n }\n\n models.set(binding.declaration, binding.model);\n\n for (const command of binding.commands) {\n // D197: one Call is one command of the mount, however many fields of the models name it. A second name is an\n // alias, not a second command, so it shares the record, the activation and the fence.\n if (bound.has(command)) continue;\n\n bound.add(command);\n commands.push(command);\n }\n }\n\n return { commands: Object.freeze(commands), frame: { commandRecords: new Map(), models } };\n}\n\n/**\n * The lifetime of one mounted contribution. `attach` claims it for the renderer, `detach` schedules the close on the\n * next microtask so a StrictMode remount reuses the same mount, and `close` fences every command it granted (D85).\n */\nclass MountFrameImpl {\n readonly frame: Frame;\n private authority: CallAuthority | undefined;\n private boundCommands: readonly AnyCommand[];\n private closeTicket = 0;\n private readonly isActive: (() => boolean) | undefined;\n private readonly lifetime: ReturnType<typeof createLifetimeController>;\n private onClose: (() => void) | undefined;\n private released = false;\n private rendererAttached = false;\n private readonly renderListeners = new Set<{ readonly listener: () => void }>();\n private state: 'active' | 'closed' | 'closing' | 'detached' = 'detached';\n\n constructor(models: readonly ModelBindingIdentity[], lifecycle?: MountFrameLifecycle) {\n const mountId = ++nextMountId;\n this.lifetime = createLifetimeController({ id: `contribution.${String(mountId)}` });\n this.isActive = lifecycle?.isActive;\n this.onClose = lifecycle?.onClose;\n const { commands, frame } = buildFrame(models);\n this.frame = frame;\n this.boundCommands = commands;\n this.buildCommandRecords(mountId);\n }\n\n attach(): boolean {\n if (this.state === 'closing') {\n this.closeTicket += 1;\n this.state = 'active';\n this.rendererAttached = true;\n\n return true;\n }\n\n if (this.state === 'closed') return false;\n\n if (this.state === 'active') throw new ContributionError('duplicate', 'One contribution mount cannot mount twice.');\n\n const authority = this.createAuthority(this.lifetime.open());\n\n try {\n for (const record of this.frame.commandRecords.values()) record.controller.activate();\n } catch (error) {\n this.authority = authority;\n this.state = 'active';\n this.close();\n\n throw error;\n }\n\n this.authority = authority;\n this.rendererAttached = true;\n this.state = 'active';\n\n return true;\n }\n\n close(): void {\n if (this.state === 'closed') return;\n\n this.state = 'closed';\n this.closeTicket += 1;\n this.lifetime.close();\n this.authority = undefined;\n\n for (const record of this.frame.commandRecords.values()) record.controller.close();\n\n const onClose = this.onClose;\n this.onClose = undefined;\n onClose?.();\n this.publishRenderable();\n\n if (!this.rendererAttached) this.releaseFrame();\n }\n\n detach(): void {\n if (!this.rendererAttached) return;\n\n this.rendererAttached = false;\n\n if (this.state === 'closed') {\n this.releaseFrame();\n\n return;\n }\n\n if (this.state !== 'active') return;\n\n this.state = 'closing';\n const ticket = ++this.closeTicket;\n\n queueMicrotask(() => {\n if (this.state === 'closing' && ticket === this.closeTicket) this.close();\n });\n }\n\n diagnostics(): MountFrameDiagnostics {\n const calls = [...this.frame.commandRecords.values()].map(record => record.controller.diagnostics());\n\n return Object.freeze({\n active: this.state === 'active',\n calls: Object.freeze(calls),\n commandRecords: this.frame.commandRecords.size,\n models: this.frame.models.size,\n });\n }\n\n getRenderableSnapshot = (): boolean => this.state !== 'closed' && (this.isActive === undefined || this.isActive());\n\n releaseClosedFrame(): void {\n if (this.state === 'closed') this.releaseFrame();\n }\n\n subscribeRenderable = (listener: () => void): (() => void) => {\n if (this.state === 'closed') return (): void => undefined;\n\n const registration = { listener };\n this.renderListeners.add(registration);\n let subscribed = true;\n\n return (): void => {\n if (!subscribed) return;\n\n subscribed = false;\n this.renderListeners.delete(registration);\n };\n };\n\n private buildCommandRecords(mountId: number): void {\n let commandIndex = 0;\n\n // `buildFrame` already reduced the models to their distinct Calls, so every command here gets its own record.\n for (const command of this.boundCommands) {\n // Authenticity check only: the binding carries no mode since observe was removed (D71).\n getCommandBindingDefinition(command);\n const controller = createCallController(command, {\n captureAuthority: this.captureAuthority,\n id: `contributionCommand.${String(mountId)}.${String(++commandIndex)}`,\n scheduling: { policy: 'parallel' },\n });\n this.frame.commandRecords.set(command, { controller, invoker: Object.freeze({ run: controller.run }) });\n }\n }\n\n private captureAuthority = (): CallAuthority => {\n const authority = this.authority;\n\n if (this.state !== 'active' || authority === undefined) {\n throw new ContributionError('inactive', 'Contribution mount is not active.');\n }\n\n authority.assertCurrent();\n\n return authority;\n };\n\n private createAuthority(lease: LifetimeLease): CallAuthority {\n return Object.freeze({\n assertCurrent: (): void => {\n if (this.state !== 'active') throw new ContributionError('inactive', 'Contribution mount is not active.');\n\n lease.assertCurrent();\n },\n isCurrent: (): boolean => this.state === 'active' && lease.isCurrent(),\n });\n }\n\n private publishRenderable(): void {\n for (const { listener } of [...this.renderListeners]) {\n try {\n listener();\n } catch (error) {\n reportDetachedError(error);\n }\n }\n }\n\n private releaseFrame(): void {\n if (this.released) return;\n\n this.released = true;\n this.frame.commandRecords.clear();\n this.frame.models.clear();\n this.boundCommands = [];\n this.renderListeners.clear();\n }\n}\n\nexport { MountFrameImpl };\nexport type { Frame };\n","import { useInsertionEffect, useLayoutEffect, useSyncExternalStore } from 'react';\nimport type { PropsWithChildren, ReactElement } from 'react';\n\nimport { FrameContext } from './mount-context';\nimport type { MountFrameImpl } from './mount-frame';\n\nfunction MountProvider({\n children,\n mount,\n}: PropsWithChildren<{ readonly mount: MountFrameImpl }>): ReactElement | null {\n const renderable = useSyncExternalStore(\n mount.subscribeRenderable,\n mount.getRenderableSnapshot,\n mount.getRenderableSnapshot,\n );\n\n useInsertionEffect(() => {\n const attached = mount.attach();\n\n if (!attached) return undefined;\n\n return () => mount.detach();\n }, [mount]);\n\n useLayoutEffect(() => {\n if (!renderable) mount.releaseClosedFrame();\n }, [mount, renderable]);\n\n return renderable ? <FrameContext value={mount.frame}>{children}</FrameContext> : null;\n}\n\nexport { MountProvider };\n","import { memo, useCallback, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';\nimport type { ComponentType, ReactElement } from 'react';\n\nimport type { DeclarationId, State } from '@opetope/core';\nimport {\n createAggregateError,\n createState,\n getContributionOwner,\n isReadable,\n reportDetachedError,\n} from '@opetope/core/internal';\nimport type { ModelIdentity } from '@opetope/core/internal';\nimport { openContributionModels, reportRuntimeFailure, requireContributionModelPlans } from '@opetope/runtime/internal';\nimport type { ContributionModelBundle, RuntimeErrorReporter } from '@opetope/runtime/internal';\n\nimport { bindCommand, isCommandBinding } from './command';\nimport { ContributionIsolation, useContributionErrorContent } from './contribution-isolation';\nimport { bindModel } from './model-binding';\nimport { isResource } from './resource-command';\nimport type { ModelBindingIdentity } from './model-binding';\nimport { MountFrameImpl } from './mount-frame';\nimport { MountProvider } from './mount-provider';\nimport { useReadable } from './readable-hooks';\n\ntype AnyModel = ModelIdentity;\ntype ContributionAuthority = {\n /** The feature whose generation published this contribution (D257). */\n readonly feature?: DeclarationId;\n readonly models: readonly (readonly [AnyModel, unknown])[];\n /** The reporter of the feature that published this contribution: a contained failure is its diagnostic, not ours. */\n readonly reporter?: RuntimeErrorReporter;\n};\ntype ModelFixture = readonly [declaration: AnyModel, model: unknown];\n\ntype ContributionValue = {\n readonly Component: ComponentType<never>;\n readonly models?: readonly object[] | undefined;\n readonly props?: ((slotProps: never) => object) | undefined;\n};\n\ntype ContributionMountProps = {\n readonly authority?: ContributionAuthority | undefined;\n readonly contribution: ContributionValue;\n /** The published entry this mount renders, and the slot it renders in: the identity of a contained failure (D257). */\n readonly contributionId: DeclarationId;\n readonly fixtures?: readonly ModelFixture[];\n readonly slotProps: object;\n readonly targetId: DeclarationId;\n};\n\ntype MountBundle = {\n readonly frame: MountFrameImpl;\n readonly isOpen: () => boolean;\n readonly props: State<object>;\n};\n\ntype MountOwner = {\n readonly authority: ContributionAuthority | undefined;\n bundle: MountBundle | undefined;\n readonly contribution: ContributionValue;\n readonly fixtures: readonly ModelFixture[] | undefined;\n retired: boolean;\n};\n\ntype CommittedMount = {\n readonly bundle: MountBundle;\n readonly owner: MountOwner;\n};\n\nfunction closeOwnedMount(owner: MountOwner): void {\n const bundle = owner.bundle;\n owner.bundle = undefined;\n bundle?.frame.close();\n}\n\n/**\n * Model fields arrive as authentic kernel calls; binding them registers the command records the frame needs. D349: a\n * Resource is none of those and needs none of it — it is a field the selection reads on its own terms, so it travels\n * to the frame unchanged instead of being offered to `bindCommand`, which would refuse it as inauthentic.\n */\nfunction bindFrameModel(declaration: AnyModel, model: unknown): ModelBindingIdentity {\n if (typeof model !== 'object' || model === null) return bindModel(declaration as never, model as never);\n\n const passesThrough = (value: unknown): boolean =>\n isReadable(value) || isResource(value) || typeof value === 'function' || isCommandBinding(value);\n const fields = Object.entries(model).map(([key, value]): readonly [string, unknown] => [\n key,\n passesThrough(value) ? value : bindCommand(value as never),\n ]);\n\n return bindModel(declaration as never, Object.fromEntries(fields) as never);\n}\n\n/**\n * D70: the authority of a contribution belongs to the entry a feature published, not to the value it wrote. One\n * static contribution object may be published by two features, and each mount must read the models of its own.\n */\nfunction contributionAuthority(entry: unknown): ContributionAuthority | undefined {\n return getContributionOwner(entry) as ContributionAuthority | undefined;\n}\n\n/** A mount with no publishing generation behind it: a fixture of a component test grants nothing and reports nowhere. */\nconst unownedContribution: ContributionAuthority = { models: [] };\n\nfunction cleanupFailedMount(close: () => void, cause: unknown): never {\n try {\n close();\n } catch (error) {\n throw createAggregateError([cause, error], 'Contribution mount setup and cleanup failed.', { cause });\n }\n\n throw cause;\n}\n\nfunction contributionModels(\n contribution: ContributionValue,\n slotProps: object,\n fixtures: readonly ModelFixture[],\n owner: ContributionAuthority | undefined,\n): {\n readonly bundle: ContributionModelBundle | undefined;\n readonly models: readonly ModelFixture[];\n readonly props: State<object>;\n} {\n const props = createState(slotProps);\n const { models: granted, reporter } = owner ?? unownedContribution;\n\n try {\n const plans = requireContributionModelPlans(contribution.models);\n const bundle = plans.length === 0 ? undefined : openContributionModels(plans, props, reporter);\n\n return {\n bundle,\n models: [...granted, ...(bundle?.models ?? []), ...fixtures],\n props,\n };\n } catch (error) {\n return cleanupFailedMount(props.close, error);\n }\n}\n\nfunction createMountBundle(\n contribution: ContributionValue,\n slotProps: object,\n fixtures: readonly ModelFixture[],\n authority: ContributionAuthority | undefined,\n): MountBundle {\n const { bundle, models, props } = contributionModels(contribution, slotProps, fixtures, authority);\n let closed = false;\n const close = (): void => {\n if (closed) return;\n\n closed = true;\n\n try {\n void bundle?.close().catch(reportDetachedError);\n } finally {\n props.close();\n }\n };\n try {\n const frame = new MountFrameImpl(\n models.map(([declaration, model]) => bindFrameModel(declaration, model)),\n { isActive: () => !closed, onClose: close },\n );\n\n return { frame, isOpen: () => !closed, props };\n } catch (error) {\n return cleanupFailedMount(close, error);\n }\n}\n\nfunction createComponentElement(Component: ComponentType<never>, props: object): ReactElement {\n const Rendered = Component as ComponentType<object>;\n\n return <Rendered {...props} />;\n}\n\ntype MountedContributionProps = {\n readonly bundle: MountBundle;\n readonly contribution: ContributionValue;\n};\n\n/** Reads the committed props of one live mount: every hook here sees a bundle that already exists. */\nfunction MountedContribution({ bundle, contribution }: MountedContributionProps): ReactElement {\n const committedProps = useReadable(bundle.props);\n const componentProps = useMemo(\n () => (contribution.props === undefined ? committedProps : contribution.props(committedProps as never)),\n [committedProps, contribution],\n );\n\n return (\n <MountProvider mount={bundle.frame}>{createComponentElement(contribution.Component, componentProps)}</MountProvider>\n );\n}\n\n/**\n * D188: a mount is created in commit, never in render. The first pass renders nothing, the layout effect builds the\n * bundle from the props that committed and publishes it, and React flushes that update before paint. A render that\n * is thrown away — StrictMode's double invoke, an abandoned concurrent pass, a suspended sibling — therefore\n * creates no models at all, so there is nothing to sweep, adopt or replace.\n */\nfunction ContributionMount({\n authority,\n contribution,\n fixtures,\n slotProps,\n}: ContributionMountProps): ReactElement | null {\n const owner = useMemo<MountOwner>(\n () => ({ authority, bundle: undefined, contribution, fixtures, retired: false }),\n [authority, contribution, fixtures],\n );\n const [committed, setCommitted] = useState<CommittedMount | undefined>(undefined);\n const bundle = committed?.owner === owner ? committed.bundle : undefined;\n const committedSlotProps = useRef(slotProps);\n\n useLayoutEffect(() => {\n committedSlotProps.current = slotProps;\n });\n\n // Suspense disconnects layout effects while hiding, but insertion cleanup only retires an actual identity.\n // Do not close Readables in insertion: their listeners may update React. A hidden tree has no layout cleanup\n // left to run on unmount, so the microtask also releases a mount that never becomes visible again.\n useInsertionEffect(\n () => () => {\n owner.retired = true;\n queueMicrotask(() => {\n try {\n closeOwnedMount(owner);\n } catch (error) {\n reportDetachedError(error);\n }\n });\n },\n [owner],\n );\n\n // The identity of the contribution owns the mount; a reveal and StrictMode reuse what its first commit created.\n useLayoutEffect(() => {\n const created = (owner.bundle ??= createMountBundle(\n owner.contribution,\n committedSlotProps.current,\n owner.fixtures ?? [],\n owner.authority,\n ));\n setCommitted(current => (current?.owner === owner ? current : { bundle: created, owner }));\n\n return () => {\n if (owner.retired) closeOwnedMount(owner);\n };\n }, [owner]);\n\n // Both the component and its models read the same committed snapshot, published before paint.\n useLayoutEffect(() => {\n if (bundle?.isOpen() === true) bundle.props.set(slotProps);\n }, [bundle, slotProps]);\n\n if (bundle === undefined) return null;\n\n return <MountedContribution bundle={bundle} contribution={contribution} />;\n}\n\n/**\n * D256: every mount is a boundary. The isolation sits above `ContributionMount`, so it contains the render of the\n * component and the commit that builds the mount alike, and a retry rebuilds the mount instead of reusing the bundle\n * that failed. Containment is unconditional; the content a failure shows is the host policy of `ContributionBoundary`.\n */\nfunction IsolatedContributionMount(props: ContributionMountProps): ReactElement {\n const { authority, contribution, contributionId, fixtures, targetId } = props;\n const content = useContributionErrorContent();\n const identity = useMemo(() => ({ authority, contribution, fixtures }), [authority, contribution, fixtures]);\n const feature = authority?.feature;\n const source = useMemo(\n () => ({ contribution: contributionId, feature, target: targetId }),\n [contributionId, feature, targetId],\n );\n const reporter = authority?.reporter;\n const report = useCallback((error: unknown) => reportRuntimeFailure(error, reporter), [reporter]);\n\n return (\n <ContributionIsolation content={content} identity={identity} report={report} source={source}>\n <ContributionMount {...props} />\n </ContributionIsolation>\n );\n}\n\n/**\n * One mount, one memo: `Slot` recreates its children whenever `entries` changes, so publishing or withholding one\n * contribution used to re-render every other mount of that target. The props are the contribution, the slot props\n * and the fixtures, all of which are stable while nothing about that mount changed.\n */\nconst MemoizedContributionMount = memo(IsolatedContributionMount);\n\nexport { contributionAuthority, MemoizedContributionMount as ContributionMount };\nexport type { ContributionValue, ModelFixture };\n"],"names":["FrameContext","createContext","useFrame","frame","useContext","ContributionError","isResource","value","isResourceValue","awaitCancellable","operation","signal","resolve","reject","cancel","CallError","compatibleAbortReason","error","notifySuccess","options","notification","_a","reportDetachedError","operationInvoker","start","_input","unavailablePage","paginationOf","resource","capability","createResourceInvokers","resourceInvokers","cache","existing","invokers","identity","useSelector","readable","select","selector","isEqual","subscribe","useCallback","listener","instanceRef","useRef","instance","getSelectedSnapshot","useMemo","initialized","sourceSnapshot","selectedSnapshot","nextSource","nextSelected","nextSelectedSnapshot","selected","useSyncExternalStore","useEffect","useReadable","bindingDefinitions","bindCommand","target","isCallTarget","getCommandBindingDefinition","binding","definition","isCommandBinding","modelBindingBrand","modelBindingIdentityBrand","modelBindingMarker","registry","modelFieldValue","declaration","model","field","descriptor","snapshotModelFields","commands","fields","isReadable","bindModel","isModel","getModelBindingMetadata","metadata","nextMountId","buildFrame","supplied","models","bound","candidate","command","MountFrameImpl","lifecycle","mountId","createLifetimeController","authority","record","onClose","ticket","calls","registration","subscribed","commandIndex","controller","createCallController","lease","MountProvider","children","mount","renderable","useInsertionEffect","useLayoutEffect","_jsx","closeOwnedMount","owner","bundle","bindFrameModel","passesThrough","key","contributionAuthority","entry","getContributionOwner","unownedContribution","cleanupFailedMount","close","cause","createAggregateError","contributionModels","contribution","slotProps","fixtures","props","createState","granted","reporter","plans","requireContributionModelPlans","openContributionModels","createMountBundle","closed","createComponentElement","Component","MountedContribution","committedProps","componentProps","ContributionMount","committed","setCommitted","useState","committedSlotProps","created","current","IsolatedContributionMount","contributionId","targetId","content","useContributionErrorContent","feature","source","report","reportRuntimeFailure","ContributionIsolation","MemoizedContributionMount","memo"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import{useState as v,useInsertionEffect as k,useLayoutEffect as y,useMemo as f,useSyncExternalStore as w,useRef as O,useCallback as F,useEffect as V,createElement as P,Fragment as X}from"react";import{CallError as Y,declarationId as Z}from"@opetope/core";import{compatibleAbortReason as _,isCancellation as ee,reportDetachedError as N,isCallTarget as te,isReadable as ne,createAggregateError as se,createContributionTarget as ie}from"@opetope/core/internal";import{C as d}from"./contribution-isolation-Bzfbt4iM.js";import{u as C,r as oe,i as re,p as ae,c as ce,a as I,M as ue,b as de}from"./contribution-frame-DkNmjChZ.js";import{d as lt}from"./contribution-frame-DkNmjChZ.js";function A(t,e){var n;if(ee(e))return{reason:e,status:"cancelled"};try{const s=(n=t==null?void 0:t.onFailure)==null?void 0:n.call(t,e);s!==void 0&&Promise.resolve(s).catch(N)}catch(s){N(s)}return{error:e,status:"failed"}}function le(t){const e=t==null?void 0:t.onSuccess,n=t==null?void 0:t.signal;return e===void 0?n===void 0?void 0:{signal:n}:n===void 0?{onSuccess:e}:{onSuccess:e,signal:n}}function fe(t,e){let n;const s=new Promise(i=>{n=i});return{input:t,options:e===void 0?void 0:{...e},promise:s,resolve:n}}function he(t,e){const n=t.resolve;t.input=void 0,t.options=void 0,t.resolve=void 0,n==null||n(e)}class h{invoker;run=((e,n)=>{if(this.notify===void 0)return Promise.resolve({reason:new d("inactive","Command consumer is not mounted."),status:"cancelled"});const s=this.cancelledInput(n);if(s!==void 0)return Promise.resolve(s);const i=fe(e,n);return this.start(i),i.promise});inFlight=0;notify;constructor(e){this.invoker=e}attach(e){return this.notify=e,()=>{this.notify===e&&(this.notify=void 0)}}synchronize(){var e;(e=this.notify)==null||e.call(this,this.inFlight>0)}aborted(e){return{reason:new Y("cancelled","Command input was cancelled.",_(e)),status:"cancelled"}}cancelledInput(e){var n;return((n=e==null?void 0:e.signal)==null?void 0:n.aborted)===!0?this.aborted(e.signal):void 0}finish(e,n){var s;e.resolve!==void 0&&(this.inFlight-=1,he(e,n),(s=this.notify)==null||s.call(this,this.inFlight>0,n))}invoke(e){let n;try{n=this.invoker.run(e.input,le(e.options)),e.input=void 0}catch(s){this.finish(e,A(e.options,s));return}n.then(s=>this.finish(e,{status:"ok",value:s}),s=>this.finish(e,A(e.options,s)))}start(e){var n;this.inFlight+=1,(n=this.notify)==null||n.call(this,!0),this.invoke(e)}}const me={inFlight:!1,outcome:void 0};function be(t){return t===void 0||t.status==="cancelled"?void 0:t}function pe(t,e,n,s){return s===void 0&&t.slot===e&&t.inFlight===n}function ge(t,e,n,s){const i=be(s);if(pe(t,e,n,i))return t;const o=t.slot===e?t.outcome:void 0;return{inFlight:n,outcome:i??o,slot:e}}function ye(t){const[e]=v(()=>new WeakMap);let n=e.get(t);return n===void 0&&(n=new h(t),e.set(t,n)),n}function m(t){const[e,n]=v(()=>({inFlight:!1,outcome:void 0,slot:t}));k(()=>t.attach((r,a)=>n(c=>ge(c,t,r,a))),[t]),y(()=>t.synchronize(),[t]);const{inFlight:s,outcome:i}=e.slot===t?e:me,o=t.run;return f(()=>({inFlight:s,outcome:i,run:o}),[s,i,o])}function we(t){const n=C().commandRecords.get(t);if(n===void 0)throw new d("missing",`Command ${t.id} is not bound in this contribution.`);return m(ye(n.invoker))}const Se=()=>{},K=()=>Se,ve=()=>0,ke=Object.freeze({}),Oe=new Map;function b(t){return"kind"in t}function p(t){const e=new h(t);return{detach:void 0,hook:{inFlight:!1,outcome:void 0,run:e.run},invoker:t,slot:e}}function Ce(t,e){return t.inFlight===e.inFlight&&Object.is(t.outcome,e.outcome)}function Ee(t,e,n){const s=t.hook;if(n===void 0&&s.inFlight===e)return!1;const i=n===void 0||n.status==="cancelled"?void 0:n,o={inFlight:e,outcome:i??s.outcome,run:s.run};return Ce(s,o)?!1:(t.hook=o,!0)}function Re(t,e){return t!==void 0&&!b(t)&&t.invoker===e?t:p(e)}function H(t,e){return{invalidate:t.invalidate.hook,pagination:t.paginated?{loadNext:t.loadNext.hook,state:e.pagination}:void 0,refresh:t.refresh.hook,retry:t.retry.hook,state:e.state}}function ze(t,e){const n={invalidate:p(t.invalidate),kind:"resource",loadNext:p(t.loadNext),paginated:e.pagination!==void 0,refresh:p(t.refresh),retry:p(t.retry)};return{...n,hook:H(n,e)}}function Me(t){var n;const{hook:e}=t;return e.refresh===t.refresh.hook&&e.retry===t.retry.hook&&e.invalidate===t.invalidate.hook&&(!t.paginated||((n=e.pagination)==null?void 0:n.loadNext)===t.loadNext.hook)}function je(t,e){var n;return Object.is(t.hook.state,e.state)&&Object.is((n=t.hook.pagination)==null?void 0:n.state,e.pagination)}function xe(t,e){return Me(t)&&je(t,e)}function Fe(t,e,n){return t===void 0||!b(t)||t.refresh.invoker!==e.refresh?ze(e,n):(xe(t,n)||(t.hook=H(t,n)),t)}function Pe(t){return b(t)?[t.refresh,t.retry,t.invalidate,t.loadNext]:[t]}function $(t){var e;for(const n of Pe(t))(e=n.detach)==null||e.call(n),n.detach=void 0}function Ne(t){return t.hook}class Ie{entries=new Map;invokers=new WeakMap;listeners=new Set;revision=0;close(){for(const e of this.entries.values())$(e);this.entries.clear()}commit(e){for(const[n,s]of this.entries)e.get(n)!==s&&$(s);this.entries=e;for(const n of e.values())this.attachEntry(n)}attachEntry(e){if(b(e)){this.attachCommand(e.refresh),this.attachCommand(e.retry),this.attachCommand(e.invalidate),this.attachCommand(e.loadNext);return}this.attachCommand(e)}attachCommand(e){e.detach??(e.detach=e.slot.attach((n,s)=>{if(Ee(e,n,s)){this.revision+=1;for(const i of this.listeners)i()}}))}getSnapshot=()=>this.revision;prepare(e,n,s){const i=new Map;for(const o of Reflect.ownKeys(e)){if(!Object.prototype.propertyIsEnumerable.call(e,o))continue;const r=e[o],a=r===void 0?void 0:s.commandRecords.get(r);if(a===void 0)throw new d("missing",`Command at ${String(o)} is not bound in this contribution.`);i.set(o,Re(this.entries.get(o),a.invoker))}for(const[o,r]of n){const a=oe(r.resource,this.invokers);i.set(o,Fe(this.entries.get(o),a,r))}return i}subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)})}function Ae(t,e){const n=O(void 0);return e.size>0||Reflect.ownKeys(t).some(i=>Object.prototype.propertyIsEnumerable.call(t,i))?n.current??(n.current=new Ie):void 0}function L(t,e){const n=C(),s=Ae(t,e),i=(s==null?void 0:s.getSnapshot)??ve;w((s==null?void 0:s.subscribe)??K,i,i);const o=s==null?void 0:s.prepare(t,e,n);return k(()=>()=>s==null?void 0:s.close(),[s]),k(()=>{o!==void 0&&(s==null||s.commit(o))}),y(()=>{if(o!==void 0)for(const r of o.values())b(r)?(r.refresh.slot.synchronize(),r.retry.slot.synchronize(),r.invalidate.slot.synchronize(),r.loadNext.slot.synchronize()):r.slot.synchronize()}),o===void 0?ke:Object.fromEntries([...o].map(([r,a])=>[r,Ne(a)]))}function Ke(t){return L(t,Oe)}const T=new Map,G=Symbol("opetope.selection-closed-state");function He(t){try{return t.getSnapshot()}catch{return G}}const W=new Set;function $e(t,e){if(!ne(t))throw new d("binding-invalid","Model selection read requires a Readable.");if(e.has(t))return e.get(t);const n=t.getSnapshot();return e.set(t,n),n}function U(t,e){if(e.has(t))return e.get(t);let n;try{n=t.getSnapshot()}catch{n=G}return e.set(t,n),n}function Le(t,e,n,s){if(!re(e))return;const i=e,o=i.pagination;n.set(t,{pagination:o===void 0?void 0:U(o.state,s),resource:i,state:U(i.state,s)})}function Te(t){return t.size===0?T:t}function Ge(t,e){const s=t({read:(r,a)=>{const c=$e(r,e);return a===void 0?c:a(c)}});if(typeof s!="object"||s===null||Array.isArray(s))throw new d("binding-invalid","Model selection requires a record.");const i=[],o=new Map;for(const r of Reflect.ownKeys(s)){if(!Object.prototype.propertyIsEnumerable.call(s,r))continue;const a=s[r];i.push([r,a]),Le(r,a,o,e)}return{resources:Te(o),values:Object.fromEntries(i)}}function We(t,e){if(t.size!==e.size)return!1;for(const[n,s]of e){const i=t.get(n);if((i==null?void 0:i.resource)!==s.resource||!Object.is(i.state,s.state)||!Object.is(i.pagination,s.pagination))return!1}return!0}function Ue(t,e,n,s){const i=Reflect.ownKeys(e),o=Reflect.ownKeys(t.values);if(i.length!==o.length||n.size!==t.sources.size)return!1;for(const r of n)if(!t.sources.has(r))return!1;return We(t.resources,s)?i.every((r,a)=>o[a]===r&&Object.is(t.values[r],e[r])):!1}const E={commands:{},leases:W,resources:T,sources:new Set,values:{}};function qe(t){return Object.fromEntries(Reflect.ownKeys(t).filter(e=>te(t[e])).map(e=>[e,t[e]]))}function De(t){if(t.size===0)return W;const e=new Set;for(const n of t.values())e.add(n.resource);return e}function Be(t,e){let n,s,i=E;return()=>{const o=e.current;if(o===void 0)return E;if(n!==void 0&&s===o&&[...n].every(([u,g])=>Object.is(He(u),g)))return i;const r=new Map,{resources:a,values:c}=Ge(u=>o(t,u),r),l=new Set(r.keys());return(n===void 0||!Ue(i,c,l,a))&&(i={commands:qe(c),leases:De(a),resources:a,sources:l,values:c}),n=r,s=o,i}}const R=new Set;function q(t,e=[]){for(const n of t){const s=n.dispose;n.dispose=void 0;try{s==null||s()}catch(i){e.push(i)}}if(e.length===1)throw e[0];if(e.length>1)throw se(e,"Model selection sources failed to release.")}class Je{enabled=!1;leases=new Map;listeners=new Set;retained=R;sources=new Set;subscriptions=new Map;close(){this.enabled=!1,this.sources=new Set,this.retained=R,this.releaseAll()}commit(e,n=R){this.sources=e,this.retained=n,this.enabled=!0;try{this.synchronize()}catch(s){this.releaseAll([s])}}subscribe=e=>{const n={notify:e};this.listeners.add(n);try{this.synchronize()}catch(s){this.listeners.delete(n),this.releaseAll([s])}return()=>{this.listeners.delete(n),this.listeners.size===0&&this.releaseAll()}};add(e){const n={dispose:void 0};this.subscriptions.set(e,n);const s=e.subscribe(this.notify);if(typeof s!="function")throw new TypeError("Model selection source must return a disposer.");this.subscriptions.get(e)===n?n.dispose=s:s()}notify=()=>{for(const e of[...this.listeners])this.listeners.has(e)&&e.notify()};releaseAll(e){const n=[...this.subscriptions.values(),...this.leases.values()];this.subscriptions.clear(),this.leases.clear(),q(n,e)}removeUnselected(){const e=[];for(const[n,s]of this.subscriptions)this.sources.has(n)||(this.subscriptions.delete(n),e.push(s));for(const[n,s]of this.leases)this.retained.has(n)||(this.leases.delete(n),e.push(s));q(e)}retain(e){const n={dispose:void 0};this.leases.set(e,n);const s=e.acquire();if(typeof s!="function")throw new TypeError("Model selection resource must answer a release disposer.");this.leases.get(e)===n?n.dispose=s:s()}ready(){return this.enabled&&this.listeners.size>0}retainSelected(){for(const e of this.retained){if(!this.ready())return;this.retained.has(e)&&!this.leases.has(e)&&this.retain(e)}}subscribeSources(){for(const e of this.sources){if(!this.ready())return;this.sources.has(e)&&!this.subscriptions.has(e)&&this.add(e)}}synchronize(){this.removeUnselected(),this.subscribeSources(),this.retainSelected()}}const Qe=()=>E;function Ve(t){const e=O(void 0);return t?e.current??(e.current=new Je):void 0}function Xe(t,e){return Object.fromEntries(Reflect.ownKeys(t.values).map(n=>[n,Object.prototype.hasOwnProperty.call(e,n)?e[n]:t.values[n]]))}function Ye(t,e){const n=C();if(!n.models.has(t))throw new d("missing",`Model ${t.id} is not granted to this contribution.`);const s=n.models.get(t),i=Ve(e!==void 0),o=O(void 0);o.current=e;const r=e!==void 0,a=f(()=>r?Be(s,o):Qe,[s,r]),c=w((i==null?void 0:i.subscribe)??K,a,a),l=L(c.commands,c.resources);return y(()=>()=>i==null?void 0:i.close(),[i]),y(()=>i==null?void 0:i.commit(c.sources,c.leases),[c,i]),e===void 0?s:Xe(c,l)}function Ze(t){const e=Object.freeze([...t]);return n=>{if(n.requires!==void 0)throw new d("duplicate","Component already declares the models it requires.");return Object.defineProperty(n,"requires",{enumerable:!1,value:e}),n}}function _e(t){const[e]=v(()=>new WeakMap),n=e.get(t);if(n!==void 0)return n;const s=ce(t),i={invalidate:new h(s.invalidate),loadNext:new h(s.loadNext),refresh:new h(s.refresh),retry:new h(s.retry)};return e.set(t,i),i}function D(t,e){let n=e;return()=>{try{n=t.getSnapshot()}catch{}return n}}const B=Object.freeze({kind:"unavailable",reason:"resource-not-ready"}),et=Object.freeze({getSnapshot:()=>B,subscribe:()=>()=>{}});function tt(t){const e=t,n=ae(e),s=F(S=>t.state.subscribe(S),[t]),i=f(()=>D(t.state,{kind:"idle",reason:"unleased"}),[t]),o=w(s,i,i),r=(n==null?void 0:n.state)??et,a=F(S=>r.subscribe(S),[r]),c=f(()=>D(r,B),[r]),l=w(a,c,c);V(()=>t.acquire(),[t]);const u=_e(e),g=m(u.refresh),z=m(u.retry),M=m(u.invalidate),j=m(u.loadNext),x=f(()=>n===void 0?void 0:{loadNext:j,state:l},[n,j,l]);return f(()=>({invalidate:M,pagination:x,refresh:g,retry:z,state:o}),[M,x,g,z,o])}const J=Object.freeze({});function Q(t){return ie(t,"slot")}function nt(t){const e=Z(t),n=new Map,s=i=>{const o=n.get(i);if(o!==void 0)return o;const r=Q(`${e}/${i}`);return n.set(i,r),r};return Object.defineProperty(s,"id",{enumerable:!0,value:e}),Object.freeze(s)}function st(t){const e=I(t.target.entries),n="props"in t?t.props??J:J;return e.length===0?null:e.map(s=>P(X,{key:s.id},P(ue,{authority:de(s),contribution:s.value,contributionId:s.id,slotProps:n,targetId:t.target.id})))}export{d as ContributionError,st as Slot,Q as defineSlot,nt as defineSwitchSlot,Ze as requiresModels,we as useCommand,Ke as useCommands,Ye as useModel,I as useReadable,tt as useResource,lt as useSelector};
1
+ import{useState as O,useInsertionEffect as E,useLayoutEffect as w,useMemo as l,useSyncExternalStore as y,useRef as S,useCallback as F,useEffect as B,createElement as P,Fragment as J}from"react";import{CallError as Q,declarationId as V}from"@opetope/core";import{compatibleAbortReason as X,isCancellation as Y,reportDetachedError as N,isCallTarget as Z,isReadable as _,createAggregateError as ee,createContributionTarget as te}from"@opetope/core/internal";import{C as d}from"./contribution-isolation-Bzfbt4iM.js";import{u as C,r as ne,i as se,p as ie,c as oe,a as I,M as re,b as ae}from"./contribution-frame-DkNmjChZ.js";import{d as dt}from"./contribution-frame-DkNmjChZ.js";function A(t,e){var n;if(Y(e))return{reason:e,status:"cancelled"};try{const s=(n=t==null?void 0:t.onFailure)==null?void 0:n.call(t,e);s!==void 0&&Promise.resolve(s).catch(N)}catch(s){N(s)}return{error:e,status:"failed"}}function ce(t){const e=t==null?void 0:t.onSuccess,n=t==null?void 0:t.signal;return e===void 0?n===void 0?void 0:{signal:n}:n===void 0?{onSuccess:e}:{onSuccess:e,signal:n}}function ue(t,e){let n;const s=new Promise(i=>{n=i});return{input:t,options:e===void 0?void 0:{...e},promise:s,resolve:n}}function de(t,e){const n=t.resolve;t.input=void 0,t.options=void 0,t.resolve=void 0,n==null||n(e)}class h{invoker;run=((e,n)=>{if(this.notify===void 0)return Promise.resolve({reason:new d("inactive","Command consumer is not mounted."),status:"cancelled"});const s=this.cancelledInput(n);if(s!==void 0)return Promise.resolve(s);const i=ue(e,n);return this.start(i),i.promise});inFlight=0;notify;constructor(e){this.invoker=e}attach(e){return this.notify=e,()=>{this.notify===e&&(this.notify=void 0)}}synchronize(){var e;(e=this.notify)==null||e.call(this,this.inFlight>0)}aborted(e){return{reason:new Q("cancelled","Command input was cancelled.",X(e)),status:"cancelled"}}cancelledInput(e){var n;return((n=e==null?void 0:e.signal)==null?void 0:n.aborted)===!0?this.aborted(e.signal):void 0}finish(e,n){var s;e.resolve!==void 0&&(this.inFlight-=1,de(e,n),(s=this.notify)==null||s.call(this,this.inFlight>0,n))}invoke(e){let n;try{n=this.invoker.run(e.input,ce(e.options)),e.input=void 0}catch(s){this.finish(e,A(e.options,s));return}n.then(s=>this.finish(e,{status:"ok",value:s}),s=>this.finish(e,A(e.options,s)))}start(e){var n;this.inFlight+=1,(n=this.notify)==null||n.call(this,!0),this.invoke(e)}}const fe={inFlight:!1,outcome:void 0};function le(t){return t===void 0||t.status==="cancelled"?void 0:t}function he(t,e,n,s){return s===void 0&&t.slot===e&&t.inFlight===n}function be(t,e,n,s){const i=le(s);if(he(t,e,n,i))return t;const o=t.slot===e?t.outcome:void 0;return{inFlight:n,outcome:i??o,slot:e}}function pe(t){const[e]=O(()=>new WeakMap);let n=e.get(t);return n===void 0&&(n=new h(t),e.set(t,n)),n}function b(t){const[e,n]=O(()=>({inFlight:!1,outcome:void 0,slot:t}));E(()=>t.attach((r,a)=>n(c=>be(c,t,r,a))),[t]),w(()=>t.synchronize(),[t]);const{inFlight:s,outcome:i}=e.slot===t?e:fe,o=t.run;return l(()=>({inFlight:s,outcome:i,run:o}),[s,i,o])}function ge(t){const n=C().commandRecords.get(t);if(n===void 0)throw new d("missing",`Command ${t.id} is not bound in this contribution.`);return b(pe(n.invoker))}const me=()=>{},K=()=>me,we=()=>0,ye=Object.freeze({}),Se=new Map;function p(t){return"kind"in t}function g(t){const e=new h(t);return{detach:void 0,hook:{inFlight:!1,outcome:void 0,run:e.run},invoker:t,slot:e}}function ve(t,e){return t.inFlight===e.inFlight&&Object.is(t.outcome,e.outcome)}function ke(t,e,n){const s=t.hook;if(n===void 0&&s.inFlight===e)return!1;const i=n===void 0||n.status==="cancelled"?void 0:n,o={inFlight:e,outcome:i??s.outcome,run:s.run};return ve(s,o)?!1:(t.hook=o,!0)}function Oe(t,e){return t!==void 0&&!p(t)&&t.invoker===e?t:g(e)}function H(t,e){return{invalidate:t.invalidate.hook,pagination:t.paginated?{loadNext:t.loadNext.hook,state:e.pagination}:void 0,refresh:t.refresh.hook,retry:t.retry.hook,state:e.state}}function Ee(t,e){const n={invalidate:g(t.invalidate),kind:"resource",loadNext:g(t.loadNext),paginated:e.pagination!==void 0,refresh:g(t.refresh),retry:g(t.retry)};return{...n,hook:H(n,e)}}function Ce(t){var n;const{hook:e}=t;return e.refresh===t.refresh.hook&&e.retry===t.retry.hook&&e.invalidate===t.invalidate.hook&&(!t.paginated||((n=e.pagination)==null?void 0:n.loadNext)===t.loadNext.hook)}function Re(t,e){var n;return Object.is(t.hook.state,e.state)&&Object.is((n=t.hook.pagination)==null?void 0:n.state,e.pagination)}function ze(t,e){return Ce(t)&&Re(t,e)}function Me(t,e,n){return t===void 0||!p(t)||t.refresh.invoker!==e.refresh?Ee(e,n):(ze(t,n)||(t.hook=H(t,n)),t)}function je(t){return p(t)?[t.refresh,t.retry,t.invalidate,t.loadNext]:[t]}function $(t){var e;for(const n of je(t))(e=n.detach)==null||e.call(n),n.detach=void 0}function xe(t){return t.hook}class Fe{entries=new Map;invokers=new WeakMap;listeners=new Set;revision=0;close(){for(const e of this.entries.values())$(e);this.entries.clear()}commit(e){for(const[n,s]of this.entries)e.get(n)!==s&&$(s);this.entries=e;for(const n of e.values())this.attachEntry(n)}attachEntry(e){if(p(e)){this.attachCommand(e.refresh),this.attachCommand(e.retry),this.attachCommand(e.invalidate),this.attachCommand(e.loadNext);return}this.attachCommand(e)}attachCommand(e){e.detach??(e.detach=e.slot.attach((n,s)=>{if(ke(e,n,s)){this.revision+=1;for(const i of this.listeners)i()}}))}getSnapshot=()=>this.revision;prepare(e,n,s){const i=new Map;for(const o of Reflect.ownKeys(e)){if(!Object.prototype.propertyIsEnumerable.call(e,o))continue;const r=e[o],a=r===void 0?void 0:s.commandRecords.get(r);if(a===void 0)throw new d("missing",`Command at ${String(o)} is not bound in this contribution.`);i.set(o,Oe(this.entries.get(o),a.invoker))}for(const[o,r]of n){const a=ne(r.resource,this.invokers);i.set(o,Me(this.entries.get(o),a,r))}return i}subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)})}function Pe(t,e){const n=S(void 0);return e.size>0||Reflect.ownKeys(t).some(i=>Object.prototype.propertyIsEnumerable.call(t,i))?n.current??(n.current=new Fe):void 0}function L(t,e){const n=C(),s=Pe(t,e),i=(s==null?void 0:s.getSnapshot)??we;y((s==null?void 0:s.subscribe)??K,i,i);const o=s==null?void 0:s.prepare(t,e,n);return E(()=>()=>s==null?void 0:s.close(),[s]),E(()=>{o!==void 0&&(s==null||s.commit(o))}),w(()=>{if(o!==void 0)for(const r of o.values())p(r)?(r.refresh.slot.synchronize(),r.retry.slot.synchronize(),r.invalidate.slot.synchronize(),r.loadNext.slot.synchronize()):r.slot.synchronize()}),o===void 0?ye:Object.fromEntries([...o].map(([r,a])=>[r,xe(a)]))}function Ne(t){return L(t,Se)}const T=new Map,U=new Set;function Ie(t,e){if(!_(t))throw new d("binding-invalid","Model selection read requires a Readable.");if(e.has(t))return e.get(t);const n=t.getSnapshot();return e.set(t,n),n}function W(t,e){if(e.has(t))return e.get(t);const n=t.getSnapshot();return e.set(t,n),n}function Ae(t,e,n,s){if(!se(e))return;const i=e,o=i.pagination;n.set(t,{pagination:o===void 0?void 0:W(o.state,s),resource:i,state:W(i.state,s)})}function Ke(t){return t.size===0?T:t}function He(t,e){const s=t({read:(r,a)=>{const c=Ie(r,e);return a===void 0?c:a(c)}});if(typeof s!="object"||s===null||Array.isArray(s))throw new d("binding-invalid","Model selection requires a record.");const i=[],o=new Map;for(const r of Reflect.ownKeys(s)){if(!Object.prototype.propertyIsEnumerable.call(s,r))continue;const a=s[r];i.push([r,a]),Ae(r,a,o,e)}return{resources:Ke(o),values:Object.fromEntries(i)}}function $e(t,e){if(t.size!==e.size)return!1;for(const[n,s]of e){const i=t.get(n);if((i==null?void 0:i.resource)!==s.resource||!Object.is(i.state,s.state)||!Object.is(i.pagination,s.pagination))return!1}return!0}function Le(t,e,n,s){const i=Reflect.ownKeys(e),o=Reflect.ownKeys(t.values);if(i.length!==o.length||n.size!==t.sources.size)return!1;for(const r of n)if(!t.sources.has(r))return!1;return $e(t.resources,s)?i.every((r,a)=>o[a]===r&&Object.is(t.values[r],e[r])):!1}const v={commands:{},leases:U,resources:T,sources:new Set,values:{}};function Te(t){return Object.fromEntries(Reflect.ownKeys(t).filter(e=>Z(t[e])).map(e=>[e,t[e]]))}function Ue(t){if(t.size===0)return U;const e=new Set;for(const n of t.values())e.add(n.resource);return e}function We(t){for(const[e,n]of t)if(!Object.is(e.getSnapshot(),n))return!1;return!0}function Ge(){return{model:void 0,observed:void 0,select:void 0,snapshot:v}}function qe(t,e,n){return n.model!==t&&(n.model=t,n.observed=void 0,n.select=void 0,n.snapshot=v),()=>{const s=e.current;if(s===void 0)return v;const i=n.observed;if(i!==void 0&&n.select===s&&We(i))return n.snapshot;const o=new Map,{resources:r,values:a}=He(f=>s(t,f),o),c=new Set(o.keys());return(i===void 0||!Le(n.snapshot,a,c,r))&&(n.snapshot={commands:Te(a),leases:Ue(r),resources:r,sources:c,values:a}),n.observed=o,n.select=s,n.snapshot}}const R=new Set;function G(t,e=[]){for(const n of t){const s=n.dispose;n.dispose=void 0;try{s==null||s()}catch(i){e.push(i)}}if(e.length===1)throw e[0];if(e.length>1)throw ee(e,"Model selection sources failed to release.")}class De{enabled=!1;leases=new Map;listeners=new Set;retained=R;sources=new Set;subscriptions=new Map;close(){this.enabled=!1,this.sources=new Set,this.retained=R,this.releaseAll()}commit(e,n=R){this.sources=e,this.retained=n,this.enabled=!0;try{this.synchronize()}catch(s){this.releaseAll([s])}}subscribe=e=>{const n={notify:e};this.listeners.add(n);try{this.synchronize()}catch(s){this.listeners.delete(n),this.releaseAll([s])}return()=>{this.listeners.delete(n),this.listeners.size===0&&this.releaseAll()}};add(e){const n={dispose:void 0};this.subscriptions.set(e,n);const s=e.subscribe(this.notify);if(typeof s!="function")throw new TypeError("Model selection source must return a disposer.");this.subscriptions.get(e)===n?n.dispose=s:s()}notify=()=>{for(const e of[...this.listeners])this.listeners.has(e)&&e.notify()};releaseAll(e){const n=[...this.subscriptions.values(),...this.leases.values()];this.subscriptions.clear(),this.leases.clear(),G(n,e)}removeUnselected(){const e=[];for(const[n,s]of this.subscriptions)this.sources.has(n)||(this.subscriptions.delete(n),e.push(s));for(const[n,s]of this.leases)this.retained.has(n)||(this.leases.delete(n),e.push(s));G(e)}retain(e){const n={dispose:void 0};this.leases.set(e,n);const s=e.acquire();if(typeof s!="function")throw new TypeError("Model selection resource must answer a release disposer.");this.leases.get(e)===n?n.dispose=s:s()}ready(){return this.enabled&&this.listeners.size>0}retainSelected(){for(const e of this.retained){if(!this.ready())return;this.retained.has(e)&&!this.leases.has(e)&&this.retain(e)}}subscribeSources(){for(const e of this.sources){if(!this.ready())return;this.sources.has(e)&&!this.subscriptions.has(e)&&this.add(e)}}synchronize(){this.removeUnselected(),this.subscribeSources(),this.retainSelected()}}const Be=()=>v;function Je(t){const e=S(void 0);return t?e.current??(e.current=new De):void 0}function Qe(t,e){return Object.fromEntries(Reflect.ownKeys(t.values).map(n=>[n,Object.prototype.hasOwnProperty.call(e,n)?e[n]:t.values[n]]))}function Ve(t,e){const n=C();if(!n.models.has(t))throw new d("missing",`Model ${t.id} is not granted to this contribution.`);const s=n.models.get(t),i=Je(e!==void 0),o=S(void 0);o.current=e;const r=e!==void 0,a=S(void 0),c=a.current??(a.current=Ge()),f=l(()=>r?qe(s,o,c):Be,[c,s,r]),u=y((i==null?void 0:i.subscribe)??K,f,f),m=L(u.commands,u.resources);return w(()=>()=>i==null?void 0:i.close(),[i]),w(()=>i==null?void 0:i.commit(u.sources,u.leases),[u,i]),e===void 0?s:Qe(u,m)}function Xe(t){const e=Object.freeze([...t]);return n=>{if(n.requires!==void 0)throw new d("duplicate","Component already declares the models it requires.");return Object.defineProperty(n,"requires",{enumerable:!1,value:e}),n}}function Ye(t){const[e]=O(()=>new WeakMap),n=e.get(t);if(n!==void 0)return n;const s=oe(t),i={invalidate:new h(s.invalidate),loadNext:new h(s.loadNext),refresh:new h(s.refresh),retry:new h(s.retry)};return e.set(t,i),i}const Ze=Object.freeze({kind:"unavailable",reason:"resource-not-ready"}),_e=Object.freeze({getSnapshot:()=>Ze,subscribe:()=>()=>{}});function et(t){const e=t,n=ie(e),s=F(k=>t.state.subscribe(k),[t]),i=l(()=>()=>t.state.getSnapshot(),[t]),o=y(s,i,i),r=(n==null?void 0:n.state)??_e,a=F(k=>r.subscribe(k),[r]),c=l(()=>()=>r.getSnapshot(),[r]),f=y(a,c,c);B(()=>t.acquire(),[t]);const u=Ye(e),m=b(u.refresh),z=b(u.retry),M=b(u.invalidate),j=b(u.loadNext),x=l(()=>n===void 0?void 0:{loadNext:j,state:f},[n,j,f]);return l(()=>({invalidate:M,pagination:x,refresh:m,retry:z,state:o}),[M,x,m,z,o])}const q=Object.freeze({});function D(t){return te(t,"slot")}function tt(t){const e=V(t),n=new Map,s=i=>{const o=n.get(i);if(o!==void 0)return o;const r=D(`${e}/${i}`);return n.set(i,r),r};return Object.defineProperty(s,"id",{enumerable:!0,value:e}),Object.freeze(s)}function nt(t){const e=I(t.target.entries),n="props"in t?t.props??q:q;return e.length===0?null:e.map(s=>P(J,{key:s.id},P(re,{authority:ae(s),contribution:s.value,contributionId:s.id,slotProps:n,targetId:t.target.id})))}export{d as ContributionError,nt as Slot,D as defineSlot,tt as defineSwitchSlot,Xe as requiresModels,ge as useCommand,Ne as useCommands,Ve as useModel,I as useReadable,et as useResource,dt as useSelector};
2
2
  //# sourceMappingURL=index.js.map