@owlmeans/client-planning 0.1.18-rc.28 → 0.1.18-rc.29

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  # @owlmeans/client-planning
2
2
 
3
3
  The client half of OwlMeans planning: a `PlanningFacade` over the protocol tree a server mounted
4
- with [`@owlmeans/server-planning`](../server-planning), an optional state mirror of cards, links and
5
- commits, and a commit wait that subscribes first and then long-polls. It is React-free, so the same
4
+ with [`@owlmeans/server-planning`](../server-planning), optional state mirrors of cards, links,
5
+ commits, assignees, teams, comments and mentions, and a commit wait that subscribes first and then long-polls. It is React-free, so the same
6
6
  code runs in a browser app and in a Node client. Use `@owlmeans/server-planning` instead wherever the
7
7
  planning service runs in-process.
8
8
 
9
9
  ## Installation
10
10
 
11
11
  ```bash
12
- bun add @owlmeans/client-planning@^0.1.18-rc.28
12
+ bun add @owlmeans/client-planning@^0.1.18-rc.29
13
13
  ```
14
14
 
15
15
  ## Concepts
@@ -36,9 +36,14 @@ import { appendPlanningClient, appendPlanningStores } from '@owlmeans/client-pla
36
36
  const planningProtocols = makePlanningProtocols({
37
37
  base: { alias: 'app:api:planning', path: '/planning', service: API },
38
38
  guards: DEFAULT_GUARD,
39
+ resources: true,
40
+ definitions: true,
39
41
  })
40
42
 
41
- appendPlanningClient(context, { protocols: planningProtocols, poll: 20 })
43
+ appendPlanningClient(context, {
44
+ protocols: planningProtocols, poll: 20,
45
+ scopeKey: () => `${currentEntitySlug}:${currentSessionId}`,
46
+ })
42
47
  appendPlanningStores(context)
43
48
  ```
44
49
 
@@ -81,6 +86,41 @@ appendPlanningClient(context, {
81
86
  })
82
87
  ```
83
88
 
89
+ ## Auxiliary resources and session lifecycle
90
+
91
+ The remote facade supports the same `assignees`, `teams`, `comments` and `mentions` methods as
92
+ the server, including compare-and-set writes, canonical team membership/project attachment,
93
+ effective project assignees and mention-cache rebuilding. `definitions` supports assignee types
94
+ when the server mounts writable schemas. Relationships include endpoint resource kinds and named
95
+ inverse views; models resolve schemas through their nearest primary project.
96
+
97
+ `appendPlanningStores` registers four auxiliary mirrors beside cards, links and commits. Reads
98
+ and writes through the facade update those mirrors without replacing newer versions. A resource
99
+ feed refreshes the requested subsets through the stock API:
100
+
101
+ ```ts
102
+ import { makePlanningResourceFeed } from '@owlmeans/client-planning'
103
+
104
+ const resources = makePlanningResourceFeed(context, {
105
+ assignees: { retired: false, size: 0 }, teams: { size: 0 },
106
+ comments: { card: cardId, size: 0 }, mentions: { card: cardId, size: 0 },
107
+ refresh: 5_000,
108
+ })
109
+ await resources.ready
110
+ // Read context.planningStores().assignees, teams, comments and mentions.
111
+ await resources.stop()
112
+ ```
113
+
114
+ `scopeKey` identifies the current organization slug and authenticated session. A changed key
115
+ cancels old requests and feeds, drains local mutations and clears mirrors; capture a new facade
116
+ and feed for the new session. `await context.planning().close()` releases feeds, subscriptions,
117
+ commit waits and sockets, including carriers that open late. Stopped requests cannot repopulate
118
+ cleared mirrors, even when a transport ignores cancellation.
119
+
120
+ The server derives authorization scope from credentials. Wire records omit native organization
121
+ `entityId`; the client hydrates empty advisory metadata for the shared record shape. Never use
122
+ that placeholder to authorize a request, and never send an organization record id on the wire.
123
+
84
124
  ## API
85
125
 
86
126
  - `appendPlanningClient(context, options)`, `makePlanningClientService(context, options)`
@@ -90,6 +130,8 @@ appendPlanningClient(context, {
90
130
  - `planningMirrorOf(stores)` (`makePlanningMirror`) — `.applyCommitEvent(event, facade?)`,
91
131
  `.applyReceipt(view)`, `.applyCards(cards)`
92
132
  - `makePlanningFeed(context, opts?)`
133
+ - `makePlanningResourceFeed(context, opts?)`, `PlanningResourceFeedOptions`
134
+ - `makePlanningClientLifecycle`, `PlanningClientLifecycle`; service `close()` and `scopeKey`
93
135
  - `planningContextOf(context)` (`makePlanningContextHelper`) — `.facade(scope?)`, `.model(card, scope?)`,
94
136
  `.stores()`
95
137
  - The former plain functions (`syncCards`, `applyCards`, `planningOf`, …) remain as deprecated
@@ -108,6 +150,9 @@ appendPlanningClient(context, {
108
150
  - `CommitTimeout` leaves the transition pending — re-wait or re-read, do not re-execute without a `key`.
109
151
  - A client refuses `store()`, `committed()` and plugins carrying hooks with `PlanningUnsupported`.
110
152
  - Mount one feed per screen; every other reader uses the store.
153
+ - Auxiliary updates/removals require `{ version: record.version }`. Their `fields` replace the
154
+ previous object; card `changes.fields` merge.
155
+ - After a scope/session change, acquire new facades and feeds. Old ones are deliberately stale.
111
156
 
112
157
  ## Related packages
113
158
 
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 2,
3
3
  "package": "@owlmeans/client-planning",
4
- "version": "0.1.18-rc.28",
5
- "generatedAt": "2026-10-09T14:39:40.666Z",
4
+ "version": "0.1.18-rc.29",
5
+ "generatedAt": "2026-10-09T20:19:04.322Z",
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.28"` in `dependencies`
11
+ **Install:** `"@owlmeans/client-planning": "^0.1.18-rc.29"` 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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/client-planning",
3
- "version": "0.1.18-rc.28",
3
+ "version": "0.1.18-rc.29",
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",
@@ -29,7 +29,7 @@
29
29
  "@owlmeans/context": "^0.1.18-rc.34",
30
30
  "@owlmeans/entrypoint": "^0.1.18-rc.41",
31
31
  "@owlmeans/error": "^0.1.18-rc.38",
32
- "@owlmeans/planning": "^0.1.18-rc.24",
32
+ "@owlmeans/planning": "^0.1.18-rc.26",
33
33
  "@owlmeans/resource": "^0.1.18-rc.40",
34
34
  "@owlmeans/log": "^0.1.18-rc.3",
35
35
  "@owlmeans/route": "^0.1.18-rc.35",
@@ -42,7 +42,7 @@
42
42
  },
43
43
  "devDependencies": {
44
44
  "@owlmeans/dep-config": "workspace:*",
45
- "@owlmeans/server-planning": "^0.1.18-rc.28",
45
+ "@owlmeans/server-planning": "^0.1.18-rc.30",
46
46
  "@owlmeans/test": "^0.1.18-rc.36",
47
47
  "@types/bun": "^1.4.2",
48
48
  "ajv": "^8.20.0",