@owlmeans/client-planning 0.1.18-rc.2 → 0.1.18-rc.20
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/README.md +2 -2
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/client-planning/SKILL.md +39 -16
- package/build/client.d.ts.map +1 -1
- package/build/client.js +7 -0
- package/build/client.js.map +1 -1
- package/build/definitions.d.ts +13 -0
- package/build/definitions.d.ts.map +1 -0
- package/build/definitions.js +64 -0
- package/build/definitions.js.map +1 -0
- package/build/facade.d.ts.map +1 -1
- package/build/facade.js +13 -2
- package/build/facade.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/types.d.ts +16 -1
- package/build/types.d.ts.map +1 -1
- package/package.json +14 -14
- package/src/client.ts +9 -0
- package/src/definitions.ts +88 -0
- package/src/facade.ts +14 -2
- package/src/index.ts +1 -0
- package/src/types.ts +20 -3
- package/tests/context.ts +14 -3
- package/tests/definitions.spec.ts +56 -0
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@ planning service runs in-process.
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
bun add @owlmeans/client-planning@^0.1.18-rc.
|
|
12
|
+
bun add @owlmeans/client-planning@^0.1.18-rc.20
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Concepts
|
|
@@ -119,7 +119,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
|
|
|
119
119
|
your project's skill store (`.agents/skills/`):
|
|
120
120
|
|
|
121
121
|
```sh
|
|
122
|
-
npx @owlmeans/agent-skills@^0.1.18-rc.
|
|
122
|
+
npx @owlmeans/agent-skills@^0.1.18-rc.46
|
|
123
123
|
```
|
|
124
124
|
|
|
125
125
|
The embedded files are version-matched to this package release. Do not edit them
|
package/agent-meta/manifest.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 2,
|
|
3
3
|
"package": "@owlmeans/client-planning",
|
|
4
|
-
"version": "0.1.18-rc.
|
|
5
|
-
"generatedAt": "2026-
|
|
4
|
+
"version": "0.1.18-rc.20",
|
|
5
|
+
"generatedAt": "2026-10-04T01:01:54.403Z",
|
|
6
6
|
"canonicalRepo": "https://github.com/owlmeans/common",
|
|
7
7
|
"entries": [
|
|
8
8
|
{
|
|
@@ -8,7 +8,7 @@ user-invocable: false
|
|
|
8
8
|
# @owlmeans/client-planning
|
|
9
9
|
|
|
10
10
|
**Layer:** Client
|
|
11
|
-
**Install:** `"@owlmeans/client-planning": "^0.1.18-rc.
|
|
11
|
+
**Install:** `"@owlmeans/client-planning": "^0.1.18-rc.20"` in `dependencies`
|
|
12
12
|
|
|
13
13
|
The client half of OwlMeans planning. It answers the `PlanningFacade` interface of
|
|
14
14
|
`@owlmeans/planning` over the protocol tree a server mounted with `@owlmeans/server-planning`, keeps
|
|
@@ -24,13 +24,14 @@ CLI). React hooks over the mirror are `useStoreModel` / `useStoreList` from `@ow
|
|
|
24
24
|
| `makePlanningClientService(context, options)` | The service itself, for a host that registers it on its own |
|
|
25
25
|
| `makeRemoteFacade(context, protocols, scope, opts)` | One facade — every method is one entrypoint call |
|
|
26
26
|
| `makeRemoteCommitSource(context, protocols, opts?)` | `status` / `subscribe` / `wait` over `commit.get` and `commit.events` |
|
|
27
|
+
| `makeRemoteDefinitions(context, protocols, opts?)` | Data-defined types and flows over a tree declared with `definitions: true` |
|
|
27
28
|
| `appendPlanningStores(context, aliases?)` / `planningStoresOf(context)` | The state mirror, and a lookup that answers `null` without one |
|
|
28
29
|
| `syncCards(store, items, where?, opts?)` / `syncLinks(...)` | Make the mirror agree with a list WITHIN a scope |
|
|
29
30
|
| `applyCommitEvent(stores, event, facade?)` / `applyReceipt(stores, view)` / `applyCards(stores, cards)` | The folds |
|
|
30
31
|
| `makePlanningFeed(context, opts?)` | Subscribe, seed, fold, refresh — `{ connected, seeded, error, ready, refresh, stop }` |
|
|
31
32
|
| `planningOf(context, scope?)` / `planningModelOf(context, card, scope?)` | The facade / a model with the schemas loaded |
|
|
32
33
|
| `CARDS`, `LINKS`, `COMMITS` | Store aliases (`planning-card-state`, `planning-link-state`, `planning-commit-state`) |
|
|
33
|
-
| Types | `PlanningClientOptions`, `PlanningClientService`, `WithPlanningClient`, `PlanningSocketOpener`, `RemoteCommitSource`, `PlanningStores`, `PlanningStoreAliases`, `WithPlanningStores`, `PlanningCommitRecord`, `PlanningFeed`, `PlanningFeedOptions`, `PlanningFeedState`, `SyncOptions` |
|
|
34
|
+
| Types | `PlanningClientOptions`, `PlanningClientService`, `WithPlanningClient`, `PlanningSocketOpener`, `RemoteCommitSource`, `RemoteDefinitions`, `RemoteDefinitionsOptions`, `PlanningStores`, `PlanningStoreAliases`, `WithPlanningStores`, `PlanningCommitRecord`, `PlanningFeed`, `PlanningFeedOptions`, `PlanningFeedState`, `SyncOptions` |
|
|
34
35
|
|
|
35
36
|
## Wiring
|
|
36
37
|
|
|
@@ -59,8 +60,8 @@ appendPlanningStores(context) // a browser mirror; a Node client usually
|
|
|
59
60
|
- `bind: false` when the host already bound the tree.
|
|
60
61
|
- The service answers under `PLANNING_SERVICE`, the alias the server's service uses, so
|
|
61
62
|
`context.planning().for(scope)` is the same call in a handler and in a screen. The scope is
|
|
62
|
-
**advisory
|
|
63
|
-
`actor` is never sent.
|
|
63
|
+
**advisory** — it changes nothing the server decides: the server takes the entity and the actor
|
|
64
|
+
from the credential. The execution's own `actor` is never sent.
|
|
64
65
|
- A client runs no middleware and folds nothing: `store()`, `committed()` and a plugin carrying
|
|
65
66
|
`before`/`after`/`store`/`mintCode` answer `PlanningUnsupported`. `use()` accepts a schemas-only
|
|
66
67
|
plugin, layered over the server's bundle.
|
|
@@ -75,16 +76,42 @@ there is swallowed — a browser that is not signed in yet cannot read it, and a
|
|
|
75
76
|
fail or wait over it. `model()` and `service.loadSchemas()` load it on first use regardless, and a
|
|
76
77
|
failed load is retried by the next caller. `schemas: false` skips the background load.
|
|
77
78
|
|
|
79
|
+
### Data-defined types and flows
|
|
80
|
+
|
|
81
|
+
A tree declared with `definitions: true` (the server's store holds data-defined schemas) gives the
|
|
82
|
+
service and every facade `definitions`: `registry(project?)` / `bundle(project?)` read
|
|
83
|
+
`schema.list?project=` and are cached per project; `putType`/`putFlow` (compare-and-set on the
|
|
84
|
+
declaration's `version`), `define`, `seed` and `retire` go through `schema.define` and drop the
|
|
85
|
+
whole cache — an organization-wide write reaches every project's layer — and make the next
|
|
86
|
+
`model()` reload the service's own bundle. `records` is the server's alone (`PlanningUnsupported`).
|
|
87
|
+
`model(card)` of a card resolves its type in its project's layer (a project's own id, a card's
|
|
88
|
+
`parent`); a specification's type is always code's. A tree without `definitions` has none of this.
|
|
89
|
+
|
|
90
|
+
## Mounting in a target
|
|
91
|
+
|
|
92
|
+
The web half of the target mount (`planning` → Mounting in a target).
|
|
93
|
+
|
|
94
|
+
- `appendPlanningClient(context, { protocols, bind: false, schemas: false })` — the target binds
|
|
95
|
+
its whole api tree itself, and a signed-out visitor may read nothing, so the bundle loads on
|
|
96
|
+
first use — plus `appendPlanningStores(context)`. No `socket`: the target serves no commit socket,
|
|
97
|
+
so `commits.wait` long-polls.
|
|
98
|
+
- Screens read the mirror with `useStoreList` / `useStoreModel` (`@owlmeans/client`), never a
|
|
99
|
+
fetched array kept in component state; lists reach the store through `syncCards` or
|
|
100
|
+
`makePlanningFeed` (with `refresh`), NEVER `replace()` — the one card store holds every kind.
|
|
101
|
+
- Every write is `facade.execute(...)` with a `key` (a retried click or a double submit answers
|
|
102
|
+
the first receipt) and `{ wait: true }` where the screen shows the result.
|
|
103
|
+
- Never call a route with an empty id; a picker offers no archived parent (`intrinsic: closed`).
|
|
104
|
+
|
|
78
105
|
## Reading
|
|
79
106
|
|
|
80
107
|
```typescript
|
|
81
108
|
const planning = context.planning().for()
|
|
82
109
|
|
|
83
|
-
const
|
|
84
|
-
const board = await planning.cards.summary([
|
|
85
|
-
const
|
|
86
|
-
const
|
|
87
|
-
|
|
110
|
+
const tools = await planning.cards.list({ parent: shedId, type: 'shed:tool', sort: ['order'], size: 0 })
|
|
111
|
+
const board = await planning.cards.summary([shedId])
|
|
112
|
+
const rules = await planning.specifications.current(shedId, 'house-rules')
|
|
113
|
+
const drill = await planning.model(drillId)
|
|
114
|
+
drill.available().map(rule => rule.name)
|
|
88
115
|
```
|
|
89
116
|
|
|
90
117
|
- The facade takes the rich `WorkcardQuery`; it encodes the scalar wire shape itself
|
|
@@ -124,8 +151,8 @@ The fold rules, shared by `syncCards`, `applyCards`, `applyCommitEvent` and `com
|
|
|
124
151
|
|
|
125
152
|
```typescript
|
|
126
153
|
const feed = makePlanningFeed(context, {
|
|
127
|
-
query: { parent:
|
|
128
|
-
filter: { project:
|
|
154
|
+
query: { parent: shedId, type: 'shed:tool' },
|
|
155
|
+
filter: { project: shedId },
|
|
129
156
|
refresh: 15_000,
|
|
130
157
|
onChange: state => setState(state),
|
|
131
158
|
})
|
|
@@ -185,18 +212,14 @@ A Node client passes no opener and relies on the long poll.
|
|
|
185
212
|
(run by `execute` whenever stores are registered) raises the stored card's `head` to the new
|
|
186
213
|
transition's `seq`, so `model.pending()` is true before any frame arrives; the commit's fold brings
|
|
187
214
|
`seq` up to it. The mirror only ever grows `head`, so a list fetched before the append does not
|
|
188
|
-
clear the marker. A model's
|
|
189
|
-
gets `WorkcardConflict` — reload and retry.
|
|
215
|
+
clear the marker. A model's `expectSeq` default and its `WorkcardConflict` are `planning` → Models.
|
|
190
216
|
|
|
191
217
|
## Gotchas
|
|
192
218
|
|
|
193
219
|
- Mount a feed once per screen; read the store everywhere else.
|
|
194
|
-
- Do not `replace()` the card store — it holds every kind. Use `syncCards` with a `where`.
|
|
195
220
|
- A refusal crosses the hop as its class (`IllegalTransition`, `WorkcardConflict`,
|
|
196
221
|
`FieldsInvalid`, a plugin's own class) — branch on `instanceof`, never on message text.
|
|
197
222
|
- `CommitTimeout` is not a failure of the transition; re-wait or re-read the card.
|
|
198
|
-
- The scope passed to `for()` changes nothing the server decides; it exists so code written against
|
|
199
|
-
`PlanningFacade` reads the same on both sides.
|
|
200
223
|
|
|
201
224
|
## Depends On
|
|
202
225
|
|
package/build/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EACV,MAAM,EAAE,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,kBAAkB,EAClF,MAAM,YAAY,CAAA;AAEnB;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WACrE,CAAC,WAAW,qBAAqB,KACzC,qBA4FF,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,WAChE,CAAC,WAAW,qBAAqB,KACzC,CAAC,GAAG,kBA0BN,CAAA"}
|
package/build/client.js
CHANGED
|
@@ -2,6 +2,7 @@ import { bindAll } from '@owlmeans/client-entrypoint';
|
|
|
2
2
|
import { createLazyService, MiddlewareStage, MiddlewareType } from '@owlmeans/context';
|
|
3
3
|
import { DEFAULT_PLUGIN_ORDER, makeSchemaRegistry, PLANNING_SERVICE, PlanningUnsupported, } from '@owlmeans/planning';
|
|
4
4
|
import { makeRemoteCommitSource } from './commits.js';
|
|
5
|
+
import { makeRemoteDefinitions } from './definitions.js';
|
|
5
6
|
import { makeRemoteFacade } from './facade.js';
|
|
6
7
|
import { planningStoresOf } from './stores.js';
|
|
7
8
|
/**
|
|
@@ -48,8 +49,13 @@ export const makePlanningClientService = (context, options) => {
|
|
|
48
49
|
}
|
|
49
50
|
return await loading;
|
|
50
51
|
};
|
|
52
|
+
// A write of data-defined schemas moves the organization's bundle too: the next `model()` reloads it.
|
|
53
|
+
const definitions = options.protocols.schema.define == null
|
|
54
|
+
? undefined
|
|
55
|
+
: makeRemoteDefinitions(context, options.protocols, { timeout: options.timeout, onWrite: () => { loaded = false; loading = null; } });
|
|
51
56
|
const facadeFor = (scope) => makeRemoteFacade(context, options.protocols, { ...options.scope, ...scope }, {
|
|
52
57
|
commits, schemas: registry, loadSchemas, timeout: options.timeout, stores,
|
|
58
|
+
...(definitions != null ? { definitions } : {}),
|
|
53
59
|
});
|
|
54
60
|
let fallback = null;
|
|
55
61
|
// Lazy, like the server's host: `context.planning()` answers before the context initializes.
|
|
@@ -78,6 +84,7 @@ export const makePlanningClientService = (context, options) => {
|
|
|
78
84
|
throw new PlanningUnsupported('client:committed');
|
|
79
85
|
},
|
|
80
86
|
close: async () => await commits.close(),
|
|
87
|
+
...(definitions != null ? { definitions } : {}),
|
|
81
88
|
});
|
|
82
89
|
};
|
|
83
90
|
/**
|
package/build/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEtF,OAAO,EACL,oBAAoB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,GAChF,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAK9C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,OAAU,EAAE,OAA8B,EACnB,EAAE;IACzB,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,OAAO,GAAqB,EAAE,CAAA;IACpC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAE9C,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE;QACjE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM;KAC7E,CAAC,CAAA;IAEF,MAAM,YAAY,GAAG,GAAS,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACxD,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;QACrD,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,OAAO,GAA2C,IAAI,CAAA;IAE1D,MAAM,WAAW,GAAyC,KAAK,EAAC,IAAI,EAAC,EAAE;QACrE,IAAI,MAAM,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,CAAC;YACnC,OAAO,QAAQ,CAAA;QACjB,CAAC;QACD,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC1B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;gBACzG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBACrB,YAAY,EAAE,CAAA;gBACd,MAAM,GAAG,IAAI,CAAA;gBAEb,OAAO,QAAQ,CAAA;YACjB,CAAC,CAAC,EAAE,CAAA;YACJ,OAAO,GAAG,OAAO,CAAA;YACjB,6FAA6F;YAC7F,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;gBACjB,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;oBACxB,OAAO,GAAG,IAAI,CAAA;gBAChB,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,MAAM,OAAO,CAAA;IACtB,CAAC,CAAA;IAED,MAAM,SAAS,GAAG,CAAC,KAAkD,EAAkB,EAAE,CACvF,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE;QAC3E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEtF,OAAO,EACL,oBAAoB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,mBAAmB,GAChF,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAK9C;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,OAAU,EAAE,OAA8B,EACnB,EAAE;IACzB,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,OAAO,GAAqB,EAAE,CAAA;IACpC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAA;IAE9C,MAAM,OAAO,GAAG,sBAAsB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE;QACjE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM;KAC7E,CAAC,CAAA;IAEF,MAAM,YAAY,GAAG,GAAS,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACxD,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;QACrD,MAAM,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAA;IACvD,CAAC,CAAC,CAAA;IAEF,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,OAAO,GAA2C,IAAI,CAAA;IAE1D,MAAM,WAAW,GAAyC,KAAK,EAAC,IAAI,EAAC,EAAE;QACrE,IAAI,MAAM,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,CAAC;YACnC,OAAO,QAAQ,CAAA;QACjB,CAAC;QACD,IAAI,OAAO,IAAI,IAAI,IAAI,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,CAAC;YAC5C,MAAM,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;gBAC1B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAA;gBACzG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBACrB,YAAY,EAAE,CAAA;gBACd,MAAM,GAAG,IAAI,CAAA;gBAEb,OAAO,QAAQ,CAAA;YACjB,CAAC,CAAC,EAAE,CAAA;YACJ,OAAO,GAAG,OAAO,CAAA;YACjB,6FAA6F;YAC7F,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE;gBACjB,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;oBACxB,OAAO,GAAG,IAAI,CAAA;gBAChB,CAAC;YACH,CAAC,CAAC,CAAA;QACJ,CAAC;QAED,OAAO,MAAM,OAAO,CAAA;IACtB,CAAC,CAAA;IAED,sGAAsG;IACtG,MAAM,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,IAAI,IAAI;QACzD,CAAC,CAAC,SAAS;QACX,CAAC,CAAC,qBAAqB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,MAAM,GAAG,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAA,CAAC,CAAC,EAAE,CAAC,CAAA;IAEtI,MAAM,SAAS,GAAG,CAAC,KAAkD,EAAkB,EAAE,CACvF,gBAAgB,CAAC,OAAO,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,KAAK,EAAE,EAAE;QAC3E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM;QACzE,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,CAAA;IAEJ,IAAI,QAAQ,GAA0B,IAAI,CAAA;IAE1C,6FAA6F;IAC7F,OAAO,iBAAiB,CAAwB,gBAAgB,EAAE;QAChE,OAAO,EAAE,QAAQ;QAEjB,OAAO;QAEP,WAAW;QAEX,GAAG,EAAE,MAAM,CAAC,EAAE;YACZ,IAAI,MAAM,CAAC,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,KAAK,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,IAAI,IAAI,EAAE,CAAC;gBACrG,MAAM,IAAI,mBAAmB,CAAC,iBAAiB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;YAC/D,CAAC;YACD,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,CAAC,CAAA;YAC/E,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;gBAClB,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA;YAC7B,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;YACpB,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,oBAAoB,CAAC,CAAC,CAAA;YAC3G,YAAY,EAAE,CAAA;QAChB,CAAC;QAED,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC;QAE3B,KAAK,EAAE,GAAG,EAAE;YACV,MAAM,IAAI,mBAAmB,CAAC,cAAc,CAAC,CAAA;QAC/C,CAAC;QAED,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC;QAE7E,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,MAAM,IAAI,mBAAmB,CAAC,kBAAkB,CAAC,CAAA;QACnD,CAAC;QAED,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,MAAM,OAAO,CAAC,KAAK,EAAE;QAExC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAClC,OAAU,EAAE,OAA8B,EAClB,EAAE;IAC1B,MAAM,GAAG,GAAG,OAAiC,CAAA;IAE7C,IAAI,OAAO,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAC3B,GAAG,CAAC,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,SAAsC,CAAC,CAAC,CAAA;IAClF,CAAC;IAED,MAAM,OAAO,GAAG,yBAAyB,CAAO,OAAO,EAAE,OAAO,CAAC,CAAA;IACjE,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAC5B,GAAG,CAAC,QAAQ,GAAG,GAAG,EAAE,CAAC,GAAG,CAAC,OAAO,CAAwB,gBAAgB,CAAC,CAAA;IAEzE,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;QAC9B,GAAG,CAAC,kBAAkB,CAAC;YACrB,IAAI,EAAE,cAAc,CAAC,OAAO;YAC5B,KAAK,EAAE,eAAe,CAAC,KAAK;YAC5B,KAAK,EAAE,KAAK,IAAI,EAAE;gBAChB,IAAI,CAAC;oBACH,MAAM,OAAO,CAAC,WAAW,EAAE,CAAA;gBAC7B,CAAC;gBAAC,MAAM,CAAC;oBACP,qCAAqC;gBACvC,CAAC;YACH,CAAC;SACF,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BasicConfig, BasicContext } from '@owlmeans/context';
|
|
2
|
+
import type { PlanningProtocols } from '@owlmeans/planning';
|
|
3
|
+
import type { RemoteDefinitions, RemoteDefinitionsOptions } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Data-defined types and flows over a tree declared with `definitions: true`: a layer's registry is
|
|
6
|
+
* read through `schema.list` (with its `project`) and cached per project; every write goes through
|
|
7
|
+
* `schema.define` and drops the whole cache — an organization-wide write reaches every project's
|
|
8
|
+
* layer. The records of a layer are the server's alone (`records` refuses).
|
|
9
|
+
*
|
|
10
|
+
* @throws {PlanningUnsupported} for a tree declared without `definitions`
|
|
11
|
+
*/
|
|
12
|
+
export declare const makeRemoteDefinitions: <C extends BasicConfig, T extends BasicContext<C>>(context: T, protocols: PlanningProtocols, opts?: RemoteDefinitionsOptions) => RemoteDefinitions;
|
|
13
|
+
//# sourceMappingURL=definitions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,KAAK,EACV,iBAAiB,EAClB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAK7E;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,WAC3E,CAAC,aAAa,iBAAiB,SAAQ,wBAAwB,KACvE,iBAmEF,CAAA"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { PlanningUnsupported, SchemaWriteMode, scopedRegistryOf } from '@owlmeans/planning';
|
|
2
|
+
const clean = (record) => Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined));
|
|
3
|
+
/**
|
|
4
|
+
* Data-defined types and flows over a tree declared with `definitions: true`: a layer's registry is
|
|
5
|
+
* read through `schema.list` (with its `project`) and cached per project; every write goes through
|
|
6
|
+
* `schema.define` and drops the whole cache — an organization-wide write reaches every project's
|
|
7
|
+
* layer. The records of a layer are the server's alone (`records` refuses).
|
|
8
|
+
*
|
|
9
|
+
* @throws {PlanningUnsupported} for a tree declared without `definitions`
|
|
10
|
+
*/
|
|
11
|
+
export const makeRemoteDefinitions = (context, protocols, opts = {}) => {
|
|
12
|
+
const define = protocols.schema.define;
|
|
13
|
+
if (define == null) {
|
|
14
|
+
throw new PlanningUnsupported('client:definitions');
|
|
15
|
+
}
|
|
16
|
+
const cache = new Map();
|
|
17
|
+
const invalidate = () => {
|
|
18
|
+
cache.clear();
|
|
19
|
+
opts.onWrite?.();
|
|
20
|
+
};
|
|
21
|
+
const registry = (project) => {
|
|
22
|
+
const key = project ?? '';
|
|
23
|
+
let entry = cache.get(key);
|
|
24
|
+
if (entry == null) {
|
|
25
|
+
const loading = (async () => scopedRegistryOf(await context.entrypoint(protocols.schema.list).call({
|
|
26
|
+
query: project != null ? { project } : {}, timeout: opts.timeout,
|
|
27
|
+
})))();
|
|
28
|
+
entry = loading;
|
|
29
|
+
cache.set(key, loading);
|
|
30
|
+
// A failed read is forgotten, so the next caller asks again instead of inheriting the error.
|
|
31
|
+
loading.catch(() => {
|
|
32
|
+
if (cache.get(key) === loading) {
|
|
33
|
+
cache.delete(key);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return entry;
|
|
38
|
+
};
|
|
39
|
+
const write = async (request) => {
|
|
40
|
+
try {
|
|
41
|
+
return await context.entrypoint(define).call({ body: clean(request), timeout: opts.timeout });
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
invalidate();
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
return {
|
|
48
|
+
bundle: async (project) => (await registry(project)).bundle(),
|
|
49
|
+
registry,
|
|
50
|
+
records: async () => {
|
|
51
|
+
throw new PlanningUnsupported('client:definitions:records');
|
|
52
|
+
},
|
|
53
|
+
putType: async (type, layer) => (await write({ project: layer?.project, mode: SchemaWriteMode.Put, types: [type] })).records[0],
|
|
54
|
+
putFlow: async (flow, layer) => (await write({ project: layer?.project, mode: SchemaWriteMode.Put, flows: [flow] })).records[0],
|
|
55
|
+
define: async (declarations, layer) => (await write({ project: layer?.project, mode: SchemaWriteMode.Define, ...declarations })).records,
|
|
56
|
+
seed: async (declarations, layer) => (await write({ project: layer?.project, mode: SchemaWriteMode.Seed, ...declarations })).records,
|
|
57
|
+
retire: async (kind, key, layer) => {
|
|
58
|
+
const { records } = await write({ project: layer?.project, retire: [{ kind, key }] });
|
|
59
|
+
return records[records.length - 1];
|
|
60
|
+
},
|
|
61
|
+
invalidate,
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=definitions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../src/definitions.ts"],"names":[],"mappings":"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"}
|
package/build/facade.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAMlE,OAAO,KAAK,EACV,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAEjD,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,WACtE,CAAC,aAAa,iBAAiB,SAAS,OAAO,CAAC,aAAa,CAAC,QAAQ,mBAAmB,KACjG,
|
|
1
|
+
{"version":3,"file":"facade.d.ts","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAMlE,OAAO,KAAK,EACV,cAAc,EAAE,iBAAiB,EAAE,aAAa,EAEjD,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAErD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,WACtE,CAAC,aAAa,iBAAiB,SAAS,OAAO,CAAC,aAAa,CAAC,QAAQ,mBAAmB,KACjG,cAsJF,CAAA"}
|
package/build/facade.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CommitFailed, CommitState, DEFAULT_COMMIT_TIMEOUT, PlanningError, PlanningUnsupported, WorkcardNotFound, encodeRelationshipQuery, encodeSpecificationQuery, encodeSummaryQuery, encodeTransitionQuery, encodeWorkcardQuery, modelOf, } from '@owlmeans/planning';
|
|
1
|
+
import { CommitFailed, CommitState, DEFAULT_COMMIT_TIMEOUT, PlanningError, PlanningUnsupported, WorkcardKind, WorkcardNotFound, encodeRelationshipQuery, encodeSpecificationQuery, encodeSummaryQuery, encodeTransitionQuery, encodeWorkcardQuery, modelOf, } from '@owlmeans/planning';
|
|
2
2
|
import { applyReceipt } from './events.js';
|
|
3
3
|
/**
|
|
4
4
|
* A {@link PlanningFacade} over the remote protocol tree — every method is one entrypoint call.
|
|
@@ -122,9 +122,20 @@ export const makeRemoteFacade = (context, protocols, scope, opts) => {
|
|
|
122
122
|
model: async (card) => {
|
|
123
123
|
await opts.loadSchemas?.();
|
|
124
124
|
const record = typeof card === 'string' ? await facade.cards.get(card) : card;
|
|
125
|
-
|
|
125
|
+
// A card of a project resolves its types in that project's layer; the organization's layer
|
|
126
|
+
// is the service's own bundle, and a specification's type is always code's.
|
|
127
|
+
const project = opts.definitions == null
|
|
128
|
+
? undefined
|
|
129
|
+
: record.kind === WorkcardKind.Project ? record.id : record.kind === WorkcardKind.Card ? record.parent : undefined;
|
|
130
|
+
if (project == null) {
|
|
131
|
+
return modelOf(record, facade);
|
|
132
|
+
}
|
|
133
|
+
return modelOf(record, { ...facade, schemas: await opts.definitions.registry(project) });
|
|
126
134
|
},
|
|
127
135
|
};
|
|
136
|
+
if (opts.definitions != null) {
|
|
137
|
+
facade.definitions = opts.definitions;
|
|
138
|
+
}
|
|
128
139
|
return facade;
|
|
129
140
|
};
|
|
130
141
|
//# sourceMappingURL=facade.js.map
|
package/build/facade.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"facade.js","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE,aAAa,EAAE,mBAAmB,EAAE,gBAAgB,
|
|
1
|
+
{"version":3,"file":"facade.js","sourceRoot":"","sources":["../src/facade.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
CHANGED
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAE/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAE/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
package/build/index.js
CHANGED
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA;AAC5B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
package/build/types.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ClientConfig, ClientContext } from '@owlmeans/client-context';
|
|
2
2
|
import type { LazyService } from '@owlmeans/context';
|
|
3
3
|
import type { AbstractRequest, EntrypointProtocolDeclaration } from '@owlmeans/entrypoint';
|
|
4
|
-
import type { CommitFilter, CommitSource, CommitState, PlanningFacade, PlanningProtocols, PlanningSchemaRegistry, PlanningScope, PlanningService, Relationship, RelationshipQuery, TransitionAction, Workcard, WorkcardKind, WorkcardQuery } from '@owlmeans/planning';
|
|
4
|
+
import type { CommitFilter, CommitSource, CommitState, PlanningDefinitions, PlanningFacade, PlanningProtocols, PlanningSchemaRegistry, PlanningScope, PlanningService, Relationship, RelationshipQuery, TransitionAction, Workcard, WorkcardKind, WorkcardQuery } from '@owlmeans/planning';
|
|
5
5
|
import type { Criteria, ResourceRecord } from '@owlmeans/resource';
|
|
6
6
|
import type { Connection } from '@owlmeans/socket';
|
|
7
7
|
import type { StateAlias, StateResource } from '@owlmeans/state';
|
|
@@ -51,6 +51,19 @@ export interface PlanningClientService extends PlanningService, LazyService {
|
|
|
51
51
|
}) => Promise<PlanningSchemaRegistry>;
|
|
52
52
|
/** Release the shared commit socket. */
|
|
53
53
|
close: () => Promise<void>;
|
|
54
|
+
/** Data-defined types and flows — present when the tree was declared with `definitions: true`. */
|
|
55
|
+
definitions?: RemoteDefinitions;
|
|
56
|
+
}
|
|
57
|
+
/** The client half of `PlanningDefinitions`: layers cached per project, dropped on any write. */
|
|
58
|
+
export interface RemoteDefinitions extends PlanningDefinitions {
|
|
59
|
+
/** Forget every cached layer — the next read asks the server. */
|
|
60
|
+
invalidate: () => void;
|
|
61
|
+
}
|
|
62
|
+
export interface RemoteDefinitionsOptions {
|
|
63
|
+
/** Milliseconds, for every definitions call. */
|
|
64
|
+
timeout?: number;
|
|
65
|
+
/** Called after every write (the service reloads its own bundle on the next `model()`). */
|
|
66
|
+
onWrite?: () => void;
|
|
54
67
|
}
|
|
55
68
|
export interface WithPlanningClient {
|
|
56
69
|
planning: () => PlanningClientService;
|
|
@@ -77,6 +90,8 @@ export interface RemoteFacadeOptions {
|
|
|
77
90
|
loadSchemas?: () => Promise<PlanningSchemaRegistry>;
|
|
78
91
|
timeout?: number;
|
|
79
92
|
stores?: () => PlanningStores | null;
|
|
93
|
+
/** The data-defined schema surface, shared by every facade of the service. */
|
|
94
|
+
definitions?: RemoteDefinitions;
|
|
80
95
|
}
|
|
81
96
|
/** One row per transition the client wrote or saw settle. */
|
|
82
97
|
export interface PlanningCommitRecord extends ResourceRecord {
|
package/build/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAA;AAC1F,OAAO,KAAK,EACV,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,cAAc,EAAE,iBAAiB,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/client-planning",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.20",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "The client half of OwlMeans planning — the remote planning facade, the state mirror and its commit fold, and the subscribe-then-poll commit wait. React-free: it runs in a browser and in a Node client alike.",
|
|
6
6
|
"type": "module",
|
|
@@ -23,17 +23,17 @@
|
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@owlmeans/auth": "^0.1.18-rc.
|
|
27
|
-
"@owlmeans/client-context": "^0.1.18-rc.
|
|
28
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
29
|
-
"@owlmeans/context": "^0.1.18-rc.
|
|
30
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
31
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
32
|
-
"@owlmeans/planning": "^0.1.18-rc.
|
|
33
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
34
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
35
|
-
"@owlmeans/socket": "^0.1.18-rc.
|
|
36
|
-
"@owlmeans/state": "^0.1.18-rc.
|
|
26
|
+
"@owlmeans/auth": "^0.1.18-rc.38",
|
|
27
|
+
"@owlmeans/client-context": "^0.1.18-rc.45",
|
|
28
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.44",
|
|
29
|
+
"@owlmeans/context": "^0.1.18-rc.32",
|
|
30
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.39",
|
|
31
|
+
"@owlmeans/error": "^0.1.18-rc.36",
|
|
32
|
+
"@owlmeans/planning": "^0.1.18-rc.17",
|
|
33
|
+
"@owlmeans/resource": "^0.1.18-rc.37",
|
|
34
|
+
"@owlmeans/route": "^0.1.18-rc.33",
|
|
35
|
+
"@owlmeans/socket": "^0.1.18-rc.37",
|
|
36
|
+
"@owlmeans/state": "^0.1.18-rc.36"
|
|
37
37
|
},
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"ajv": "*",
|
|
@@ -41,8 +41,8 @@
|
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@owlmeans/dep-config": "workspace:*",
|
|
44
|
-
"@owlmeans/server-planning": "^0.1.18-rc.
|
|
45
|
-
"@owlmeans/test": "^0.1.18-rc.
|
|
44
|
+
"@owlmeans/server-planning": "^0.1.18-rc.20",
|
|
45
|
+
"@owlmeans/test": "^0.1.18-rc.33",
|
|
46
46
|
"@types/bun": "^1.4.0",
|
|
47
47
|
"ajv": "^8.17.1",
|
|
48
48
|
"ajv-formats": "^3.0.1",
|
package/src/client.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from '@owlmeans/planning'
|
|
7
7
|
import type { PlanningFacade, PlanningPlugin, PlanningSchemaRegistry } from '@owlmeans/planning'
|
|
8
8
|
import { makeRemoteCommitSource } from './commits.js'
|
|
9
|
+
import { makeRemoteDefinitions } from './definitions.js'
|
|
9
10
|
import { makeRemoteFacade } from './facade.js'
|
|
10
11
|
import { planningStoresOf } from './stores.js'
|
|
11
12
|
import type {
|
|
@@ -65,9 +66,15 @@ export const makePlanningClientService = <C extends Config, T extends Context<C>
|
|
|
65
66
|
return await loading
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
// A write of data-defined schemas moves the organization's bundle too: the next `model()` reloads it.
|
|
70
|
+
const definitions = options.protocols.schema.define == null
|
|
71
|
+
? undefined
|
|
72
|
+
: makeRemoteDefinitions(context, options.protocols, { timeout: options.timeout, onWrite: () => { loaded = false; loading = null } })
|
|
73
|
+
|
|
68
74
|
const facadeFor = (scope: Parameters<PlanningClientService['for']>[0]): PlanningFacade =>
|
|
69
75
|
makeRemoteFacade(context, options.protocols, { ...options.scope, ...scope }, {
|
|
70
76
|
commits, schemas: registry, loadSchemas, timeout: options.timeout, stores,
|
|
77
|
+
...(definitions != null ? { definitions } : {}),
|
|
71
78
|
})
|
|
72
79
|
|
|
73
80
|
let fallback: PlanningFacade | null = null
|
|
@@ -106,6 +113,8 @@ export const makePlanningClientService = <C extends Config, T extends Context<C>
|
|
|
106
113
|
},
|
|
107
114
|
|
|
108
115
|
close: async () => await commits.close(),
|
|
116
|
+
|
|
117
|
+
...(definitions != null ? { definitions } : {}),
|
|
109
118
|
})
|
|
110
119
|
}
|
|
111
120
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import type { BasicConfig, BasicContext } from '@owlmeans/context'
|
|
2
|
+
import { PlanningUnsupported, SchemaWriteMode, scopedRegistryOf } from '@owlmeans/planning'
|
|
3
|
+
import type {
|
|
4
|
+
PlanningProtocols, SchemaDefineReply, SchemaDefineRequest, ScopedSchemaRegistry,
|
|
5
|
+
} from '@owlmeans/planning'
|
|
6
|
+
import type { RemoteDefinitions, RemoteDefinitionsOptions } from './types.js'
|
|
7
|
+
|
|
8
|
+
const clean = <T extends object>(record: T): T =>
|
|
9
|
+
Object.fromEntries(Object.entries(record).filter(([, value]) => value !== undefined)) as T
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Data-defined types and flows over a tree declared with `definitions: true`: a layer's registry is
|
|
13
|
+
* read through `schema.list` (with its `project`) and cached per project; every write goes through
|
|
14
|
+
* `schema.define` and drops the whole cache — an organization-wide write reaches every project's
|
|
15
|
+
* layer. The records of a layer are the server's alone (`records` refuses).
|
|
16
|
+
*
|
|
17
|
+
* @throws {PlanningUnsupported} for a tree declared without `definitions`
|
|
18
|
+
*/
|
|
19
|
+
export const makeRemoteDefinitions = <C extends BasicConfig, T extends BasicContext<C>>(
|
|
20
|
+
context: T, protocols: PlanningProtocols, opts: RemoteDefinitionsOptions = {}
|
|
21
|
+
): RemoteDefinitions => {
|
|
22
|
+
const define = protocols.schema.define
|
|
23
|
+
if (define == null) {
|
|
24
|
+
throw new PlanningUnsupported('client:definitions')
|
|
25
|
+
}
|
|
26
|
+
const cache = new Map<string, Promise<ScopedSchemaRegistry>>()
|
|
27
|
+
|
|
28
|
+
const invalidate = (): void => {
|
|
29
|
+
cache.clear()
|
|
30
|
+
opts.onWrite?.()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const registry = (project?: string): Promise<ScopedSchemaRegistry> => {
|
|
34
|
+
const key = project ?? ''
|
|
35
|
+
let entry = cache.get(key)
|
|
36
|
+
if (entry == null) {
|
|
37
|
+
const loading = (async () => scopedRegistryOf(await context.entrypoint(protocols.schema.list).call({
|
|
38
|
+
query: project != null ? { project } : {}, timeout: opts.timeout,
|
|
39
|
+
})))()
|
|
40
|
+
entry = loading
|
|
41
|
+
cache.set(key, loading)
|
|
42
|
+
// A failed read is forgotten, so the next caller asks again instead of inheriting the error.
|
|
43
|
+
loading.catch(() => {
|
|
44
|
+
if (cache.get(key) === loading) {
|
|
45
|
+
cache.delete(key)
|
|
46
|
+
}
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
return entry
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const write = async (request: SchemaDefineRequest): Promise<SchemaDefineReply> => {
|
|
53
|
+
try {
|
|
54
|
+
return await context.entrypoint(define).call({ body: clean(request), timeout: opts.timeout })
|
|
55
|
+
} finally {
|
|
56
|
+
invalidate()
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
bundle: async project => (await registry(project)).bundle(),
|
|
62
|
+
|
|
63
|
+
registry,
|
|
64
|
+
|
|
65
|
+
records: async () => {
|
|
66
|
+
throw new PlanningUnsupported('client:definitions:records')
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
putType: async (type, layer) =>
|
|
70
|
+
(await write({ project: layer?.project, mode: SchemaWriteMode.Put, types: [type] })).records[0],
|
|
71
|
+
|
|
72
|
+
putFlow: async (flow, layer) =>
|
|
73
|
+
(await write({ project: layer?.project, mode: SchemaWriteMode.Put, flows: [flow] })).records[0],
|
|
74
|
+
|
|
75
|
+
define: async (declarations, layer) =>
|
|
76
|
+
(await write({ project: layer?.project, mode: SchemaWriteMode.Define, ...declarations })).records,
|
|
77
|
+
|
|
78
|
+
seed: async (declarations, layer) =>
|
|
79
|
+
(await write({ project: layer?.project, mode: SchemaWriteMode.Seed, ...declarations })).records,
|
|
80
|
+
|
|
81
|
+
retire: async (kind, key, layer) => {
|
|
82
|
+
const { records } = await write({ project: layer?.project, retire: [{ kind, key }] })
|
|
83
|
+
return records[records.length - 1]
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
invalidate,
|
|
87
|
+
}
|
|
88
|
+
}
|
package/src/facade.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { BasicConfig, BasicContext } from '@owlmeans/context'
|
|
2
2
|
import {
|
|
3
|
-
CommitFailed, CommitState, DEFAULT_COMMIT_TIMEOUT, PlanningError, PlanningUnsupported, WorkcardNotFound,
|
|
3
|
+
CommitFailed, CommitState, DEFAULT_COMMIT_TIMEOUT, PlanningError, PlanningUnsupported, WorkcardKind, WorkcardNotFound,
|
|
4
4
|
encodeRelationshipQuery, encodeSpecificationQuery, encodeSummaryQuery, encodeTransitionQuery,
|
|
5
5
|
encodeWorkcardQuery, modelOf,
|
|
6
6
|
} from '@owlmeans/planning'
|
|
@@ -159,11 +159,23 @@ export const makeRemoteFacade = <C extends BasicConfig, T extends BasicContext<C
|
|
|
159
159
|
model: async <R extends Workcard = Workcard>(card: R | string): Promise<WorkcardModel<R>> => {
|
|
160
160
|
await opts.loadSchemas?.()
|
|
161
161
|
const record = typeof card === 'string' ? await facade.cards.get(card) as R : card
|
|
162
|
+
// A card of a project resolves its types in that project's layer; the organization's layer
|
|
163
|
+
// is the service's own bundle, and a specification's type is always code's.
|
|
164
|
+
const project = opts.definitions == null
|
|
165
|
+
? undefined
|
|
166
|
+
: record.kind === WorkcardKind.Project ? record.id : record.kind === WorkcardKind.Card ? record.parent : undefined
|
|
167
|
+
if (project == null) {
|
|
168
|
+
return modelOf<R>(record, facade)
|
|
169
|
+
}
|
|
162
170
|
|
|
163
|
-
return modelOf<R>(record, facade)
|
|
171
|
+
return modelOf<R>(record, { ...facade, schemas: await opts.definitions!.registry(project) })
|
|
164
172
|
},
|
|
165
173
|
}
|
|
166
174
|
|
|
175
|
+
if (opts.definitions != null) {
|
|
176
|
+
facade.definitions = opts.definitions
|
|
177
|
+
}
|
|
178
|
+
|
|
167
179
|
return facade
|
|
168
180
|
}
|
|
169
181
|
|
package/src/index.ts
CHANGED
package/src/types.ts
CHANGED
|
@@ -2,9 +2,9 @@ import type { ClientConfig, ClientContext } from '@owlmeans/client-context'
|
|
|
2
2
|
import type { LazyService } from '@owlmeans/context'
|
|
3
3
|
import type { AbstractRequest, EntrypointProtocolDeclaration } from '@owlmeans/entrypoint'
|
|
4
4
|
import type {
|
|
5
|
-
CommitFilter, CommitSource, CommitState, PlanningFacade, PlanningProtocols,
|
|
6
|
-
PlanningScope, PlanningService, Relationship, RelationshipQuery, TransitionAction,
|
|
7
|
-
WorkcardKind, WorkcardQuery,
|
|
5
|
+
CommitFilter, CommitSource, CommitState, PlanningDefinitions, PlanningFacade, PlanningProtocols,
|
|
6
|
+
PlanningSchemaRegistry, PlanningScope, PlanningService, Relationship, RelationshipQuery, TransitionAction,
|
|
7
|
+
Workcard, WorkcardKind, WorkcardQuery,
|
|
8
8
|
} from '@owlmeans/planning'
|
|
9
9
|
import type { Criteria, ResourceRecord } from '@owlmeans/resource'
|
|
10
10
|
import type { Connection } from '@owlmeans/socket'
|
|
@@ -56,6 +56,21 @@ export interface PlanningClientService extends PlanningService, LazyService {
|
|
|
56
56
|
loadSchemas: (opts?: { force?: boolean }) => Promise<PlanningSchemaRegistry>
|
|
57
57
|
/** Release the shared commit socket. */
|
|
58
58
|
close: () => Promise<void>
|
|
59
|
+
/** Data-defined types and flows — present when the tree was declared with `definitions: true`. */
|
|
60
|
+
definitions?: RemoteDefinitions
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The client half of `PlanningDefinitions`: layers cached per project, dropped on any write. */
|
|
64
|
+
export interface RemoteDefinitions extends PlanningDefinitions {
|
|
65
|
+
/** Forget every cached layer — the next read asks the server. */
|
|
66
|
+
invalidate: () => void
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface RemoteDefinitionsOptions {
|
|
70
|
+
/** Milliseconds, for every definitions call. */
|
|
71
|
+
timeout?: number
|
|
72
|
+
/** Called after every write (the service reloads its own bundle on the next `model()`). */
|
|
73
|
+
onWrite?: () => void
|
|
59
74
|
}
|
|
60
75
|
|
|
61
76
|
export interface WithPlanningClient {
|
|
@@ -86,6 +101,8 @@ export interface RemoteFacadeOptions {
|
|
|
86
101
|
loadSchemas?: () => Promise<PlanningSchemaRegistry>
|
|
87
102
|
timeout?: number
|
|
88
103
|
stores?: () => PlanningStores | null
|
|
104
|
+
/** The data-defined schema surface, shared by every facade of the service. */
|
|
105
|
+
definitions?: RemoteDefinitions
|
|
89
106
|
}
|
|
90
107
|
|
|
91
108
|
/** One row per transition the client wrote or saw settle. */
|
package/tests/context.ts
CHANGED
|
@@ -86,6 +86,7 @@ const types: AnyTypeSchema[] = [
|
|
|
86
86
|
flows: [PROJECT_FLOW],
|
|
87
87
|
specifications: [{ category: 'brief', format: SpecificationFormat.Markdown, revisioned: true, type: SPEC }],
|
|
88
88
|
cardTypes: [STORY],
|
|
89
|
+
scopedCardTypes: true,
|
|
89
90
|
},
|
|
90
91
|
{
|
|
91
92
|
type: STORY,
|
|
@@ -118,6 +119,13 @@ export const protocols = makePlanningProtocols({
|
|
|
118
119
|
guards: [],
|
|
119
120
|
})
|
|
120
121
|
|
|
122
|
+
/** The same mount with the data-defined schema surface. */
|
|
123
|
+
export const definitionProtocols = makePlanningProtocols({
|
|
124
|
+
base: { alias: 'test:planning', path: '/planning' },
|
|
125
|
+
guards: [],
|
|
126
|
+
definitions: true,
|
|
127
|
+
})
|
|
128
|
+
|
|
121
129
|
const AUTH = { profileId: PROFILE_ID, userId: 'user-1', entityId: 'acme' } as unknown as Auth
|
|
122
130
|
const entityOf = (id: string): ResolvedEntity => ({ id, slug: id, iamKey: id })
|
|
123
131
|
|
|
@@ -136,6 +144,8 @@ export interface SuiteOptions extends Partial<Pick<PlanningClientOptions, 'poll'
|
|
|
136
144
|
stores?: boolean
|
|
137
145
|
/** The entity the transport authenticates as. */
|
|
138
146
|
entityId?: string
|
|
147
|
+
/** Mount the tree with `definitions: true` over a store holding data-defined schemas. */
|
|
148
|
+
definitions?: boolean
|
|
139
149
|
/** Runs after the server answered a call and before the client sees the answer. */
|
|
140
150
|
after?: (call: Call) => Promise<void>
|
|
141
151
|
}
|
|
@@ -193,9 +203,10 @@ export const makeSuite = async (opts: SuiteOptions = {}): Promise<Suite> => {
|
|
|
193
203
|
const server = makeBasicContext<BasicConfig>({
|
|
194
204
|
ready: false, service: 'client-planning-tests-server', type: AppType.Backend,
|
|
195
205
|
} as BasicConfig)
|
|
196
|
-
const
|
|
206
|
+
const tree = opts.definitions === true ? definitionProtocols : protocols
|
|
207
|
+
const store = makeMemoryPlanningStore({ sync: opts.sync !== false, schemas: opts.definitions === true })
|
|
197
208
|
appendPlanningService(server, { store, schemas: { types, flows } })
|
|
198
|
-
server.registerEntrypoints(servePlanningEntrypoints(
|
|
209
|
+
server.registerEntrypoints(servePlanningEntrypoints(tree))
|
|
199
210
|
await server.configure().init()
|
|
200
211
|
|
|
201
212
|
const calls: Call[] = []
|
|
@@ -245,7 +256,7 @@ export const makeSuite = async (opts: SuiteOptions = {}): Promise<Suite> => {
|
|
|
245
256
|
}))
|
|
246
257
|
|
|
247
258
|
appendPlanningClient(client, {
|
|
248
|
-
protocols,
|
|
259
|
+
protocols: tree,
|
|
249
260
|
poll: opts.poll ?? 2,
|
|
250
261
|
schemas: opts.schemas,
|
|
251
262
|
...(opts.socket === true
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { describe, expect, test } from 'bun:test'
|
|
2
|
+
import {
|
|
3
|
+
PlanningSchemaKind, PlanningUnsupported, SchemaOrigin, TransitionAction, WorkcardKind,
|
|
4
|
+
} from '@owlmeans/planning'
|
|
5
|
+
import type { WorkcardTypeSchema } from '@owlmeans/planning'
|
|
6
|
+
import { definitionProtocols, makeSuite, STORY_FLOW } from './context.js'
|
|
7
|
+
|
|
8
|
+
/** A choir's rehearsal card, defined as data for one project. */
|
|
9
|
+
const REHEARSAL: WorkcardTypeSchema = {
|
|
10
|
+
type: 'test:rehearsal', kind: WorkcardKind.Card, version: 1, fields: { type: 'object' }, flows: [STORY_FLOW], specifications: [],
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
describe('@owlmeans/client-planning — data-defined schemas', () => {
|
|
14
|
+
test('a layer is read once per project and read again after any write', async () => {
|
|
15
|
+
const suite = await makeSuite({ definitions: true })
|
|
16
|
+
const project = await suite.project('Spring concert')
|
|
17
|
+
const definitions = suite.planning.definitions!
|
|
18
|
+
const reads = () => suite.calls.filter(call => call.alias === definitionProtocols.schema.list.alias).length
|
|
19
|
+
|
|
20
|
+
const written = await definitions.define({ types: [REHEARSAL] }, { project: project.id })
|
|
21
|
+
expect(written.map(record => [record.kind, record.key, record.version, record.project]))
|
|
22
|
+
.toEqual([[PlanningSchemaKind.Type, REHEARSAL.type, 1, project.id]])
|
|
23
|
+
|
|
24
|
+
const before = reads()
|
|
25
|
+
const layer = await definitions.registry(project.id)
|
|
26
|
+
await definitions.registry(project.id)
|
|
27
|
+
expect(reads()).toBe(before + 1)
|
|
28
|
+
expect(layer.originOf(PlanningSchemaKind.Type, REHEARSAL.type)).toBe(SchemaOrigin.Project)
|
|
29
|
+
expect((await definitions.bundle()).types.some(type => type.type === REHEARSAL.type)).toBe(false)
|
|
30
|
+
|
|
31
|
+
await definitions.putType({ ...REHEARSAL, version: 2, label: 'Rehearsal' }, { project: project.id })
|
|
32
|
+
expect((await definitions.registry(project.id)).type(REHEARSAL.type).label).toBe('Rehearsal')
|
|
33
|
+
expect(reads()).toBe(before + 3)
|
|
34
|
+
await expect(definitions.records()).rejects.toBeInstanceOf(PlanningUnsupported)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test('a model of a card resolves its type in its own project\'s layer', async () => {
|
|
38
|
+
const suite = await makeSuite({ definitions: true })
|
|
39
|
+
const project = await suite.project('Autumn concert')
|
|
40
|
+
await suite.planning.definitions!.define({ types: [REHEARSAL] }, { project: project.id })
|
|
41
|
+
const card = (await suite.local.execute({
|
|
42
|
+
card: { kind: WorkcardKind.Card, type: REHEARSAL.type, parent: project.id!, title: 'Sectionals' },
|
|
43
|
+
action: TransitionAction.Create,
|
|
44
|
+
}, { wait: true })).card!
|
|
45
|
+
|
|
46
|
+
const model = await suite.planning.model(card.id!)
|
|
47
|
+
expect(model.schema().type).toBe(REHEARSAL.type)
|
|
48
|
+
expect(model.available().map(rule => rule.name)).toEqual(['start', 'reset'])
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
test('a tree declared without definitions has none', async () => {
|
|
52
|
+
const suite = await makeSuite()
|
|
53
|
+
expect(suite.planning.definitions).toBeUndefined()
|
|
54
|
+
expect(suite.client.planning().definitions).toBeUndefined()
|
|
55
|
+
})
|
|
56
|
+
})
|