@owlmeans/client-planning 0.1.18-rc.27 → 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 +49 -4
- package/agent-meta/manifest.json +2 -2
- package/agent-meta/skills/client-planning/SKILL.md +25 -7
- package/build/client.d.ts.map +1 -1
- package/build/client.js +31 -29
- package/build/client.js.map +1 -1
- package/build/commits.d.ts +1 -12
- package/build/commits.d.ts.map +1 -1
- package/build/commits.js +186 -130
- package/build/commits.js.map +1 -1
- package/build/definitions.d.ts.map +1 -1
- package/build/definitions.js +12 -11
- package/build/definitions.js.map +1 -1
- package/build/events/types.d.ts +8 -3
- package/build/events/types.d.ts.map +1 -1
- package/build/events.d.ts.map +1 -1
- package/build/events.js +56 -48
- package/build/events.js.map +1 -1
- package/build/facade.d.ts.map +1 -1
- package/build/facade.js +51 -47
- package/build/facade.js.map +1 -1
- package/build/feed.d.ts.map +1 -1
- package/build/feed.js +24 -11
- package/build/feed.js.map +1 -1
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/lifecycle/types.d.ts +27 -0
- package/build/lifecycle/types.d.ts.map +1 -0
- package/build/lifecycle/types.js +2 -0
- package/build/lifecycle/types.js.map +1 -0
- package/build/lifecycle.d.ts +3 -0
- package/build/lifecycle.d.ts.map +1 -0
- package/build/lifecycle.js +157 -0
- package/build/lifecycle.js.map +1 -0
- package/build/resource-feed.d.ts.map +1 -1
- package/build/resource-feed.js +32 -24
- package/build/resource-feed.js.map +1 -1
- package/build/resources.d.ts.map +1 -1
- package/build/resources.js +23 -28
- package/build/resources.js.map +1 -1
- package/build/types.d.ts +9 -2
- package/build/types.d.ts.map +1 -1
- package/build/types.local.d.ts +7 -0
- package/build/types.local.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/client.ts +26 -23
- package/src/commits.ts +148 -173
- package/src/definitions.ts +11 -10
- package/src/events/types.ts +9 -3
- package/src/events.ts +58 -49
- package/src/facade.ts +50 -48
- package/src/feed.ts +20 -11
- package/src/index.ts +2 -0
- package/src/lifecycle/types.ts +28 -0
- package/src/lifecycle.ts +123 -0
- package/src/resource-feed.ts +25 -17
- package/src/resources.ts +18 -20
- package/src/types.local.ts +8 -0
- package/src/types.ts +9 -2
- package/tests/context.ts +12 -4
- package/tests/lifecycle/context.ts +29 -0
- package/tests/lifecycle-close.spec.ts +103 -0
- package/tests/lifecycle-commits.spec.ts +92 -0
- package/tests/lifecycle-definitions.spec.ts +28 -0
- package/tests/lifecycle-feeds.spec.ts +92 -0
- package/tests/lifecycle-sockets.spec.ts +76 -0
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),
|
|
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.
|
|
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, {
|
|
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
|
|
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-10-
|
|
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.
|
|
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
|
|
@@ -239,11 +239,26 @@ Comments use trusted server authors; mentions are read-only derived cache comman
|
|
|
239
239
|
|
|
240
240
|
Supply `PlanningClientOptions.scopeKey` from authenticated organization entity slug, profile/user
|
|
241
241
|
id, session id and authorization revision; return undefined when signed out. Before switching
|
|
242
|
-
organization or signing out,
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
242
|
+
organization or signing out, **await** `service.close()` before adopting the credential. It cancels
|
|
243
|
+
requests and commit waits, invalidates receipts (including already-settled receipts), stops every
|
|
244
|
+
registered feed, removes socket subscriptions, closes the carrier and rejects late socket openers.
|
|
245
|
+
A stale operation answers `client:scope-changed`; cancellation never rolls back an accepted server
|
|
246
|
+
write. A new subscription opens a fresh carrier after close.
|
|
247
|
+
|
|
248
|
+
Close drains admitted **local** mirror writes before clearing every stock store and schema cache.
|
|
249
|
+
New calls during an explicit close are refused, including hosts without `scopeKey`. Concurrent
|
|
250
|
+
closes share the boundary. If clearing fails, close rejects and fresh work stays blocked; retain
|
|
251
|
+
the old credential and retry close explicitly. An observed identity change also cancels old work
|
|
252
|
+
and queues clearing before the new identity's mirror writes. Reload schemas and create fresh feeds
|
|
253
|
+
after credential adoption. Feed query scope alone is insufficient for this lifecycle.
|
|
254
|
+
|
|
255
|
+
The service's `lifecycle` coordinates stock facades, receipts, feeds and schema writes. A custom
|
|
256
|
+
mirror integration captures an operation with `lifecycle.run`, performs remote reads through
|
|
257
|
+
`operation.wait` with `operation.signal`, then uses `lifecycle.mutate(operation, write)` for local
|
|
258
|
+
writes; never hold or nest that queue over a request, socket opener or another queued mutation.
|
|
259
|
+
`planningMirrorOf(stores)` accepts `{ lifecycle, operation }` as its optional last argument and
|
|
260
|
+
fetches missing frame records/links before entering the queue. Direct mirror/sync helpers without
|
|
261
|
+
that option are local primitives: their caller owns isolation and cleanup.
|
|
247
262
|
|
|
248
263
|
Planning protocols return `PlanningReply<T>` without storage organization identifiers. Stock
|
|
249
264
|
facades hydrate records, receipts, schema scopes and socket frames with `entityId: ''` only to
|
|
@@ -255,7 +270,10 @@ Resource feed reconciliation snapshots mirror versions before requesting a list.
|
|
|
255
270
|
snapshot rows absent from that response are removed, so a new local write or a newer version
|
|
256
271
|
survives an older in-flight poll. Stopped feeds cannot publish. Track custom feeds through
|
|
257
272
|
`registerFeed` when their lifecycle must end with the planning service. Card feeds use the same
|
|
258
|
-
identity fence and stop registration; component cleanup
|
|
273
|
+
identity fence and stop registration; component cleanup awaits `stop()` when it must observe a
|
|
274
|
+
completed boundary. Stop cancels unresolved seeds and drains admitted local changes without waiting
|
|
275
|
+
for the network; neither late callbacks nor authoritative deletion passes may publish afterward.
|
|
276
|
+
A schema write from an old generation cannot invalidate a newer generation's cached registry.
|
|
259
277
|
|
|
260
278
|
|
|
261
279
|
## Related
|
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":"AAYA,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,qBAoHF,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
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { bindAll } from '@owlmeans/client-entrypoint';
|
|
2
2
|
import { createLazyService, MiddlewareStage, MiddlewareType } from '@owlmeans/context';
|
|
3
|
-
import { DEFAULT_PLUGIN_ORDER, makeSchemaRegistry, PLANNING_SERVICE,
|
|
3
|
+
import { DEFAULT_PLUGIN_ORDER, makeSchemaRegistry, PLANNING_SERVICE, PlanningUnsupported, } from '@owlmeans/planning';
|
|
4
4
|
import { makeRemoteCommitSource } from './commits.js';
|
|
5
5
|
import { makeRemoteDefinitions } from './definitions.js';
|
|
6
6
|
import { makeRemoteFacade } from './facade.js';
|
|
7
7
|
import { planningContextOf } from './helper.js';
|
|
8
|
+
import { makePlanningClientLifecycle } from './lifecycle.js';
|
|
8
9
|
/**
|
|
9
10
|
* The client planning service: a remote facade factory under the SAME alias the server registers
|
|
10
11
|
* its service under, so `context.planning().for(scope)` is one call on both sides.
|
|
@@ -15,14 +16,22 @@ import { planningContextOf } from './helper.js';
|
|
|
15
16
|
* bundle.
|
|
16
17
|
*/
|
|
17
18
|
export const makePlanningClientService = (context, options) => {
|
|
18
|
-
let epoch = 0;
|
|
19
|
-
const scopeKey = () => `${epoch}:${options.scopeKey?.() ?? ''}`;
|
|
20
19
|
const feeds = new Set();
|
|
21
20
|
const registry = makeSchemaRegistry();
|
|
22
21
|
const plugins = [];
|
|
23
22
|
const stores = () => planningContextOf(context).stores();
|
|
23
|
+
const lifecycle = makePlanningClientLifecycle({ scopeKey: options.scopeKey, clear: async () => {
|
|
24
|
+
const mirrors = stores();
|
|
25
|
+
if (mirrors != null)
|
|
26
|
+
for (const resource of Object.values(mirrors)) {
|
|
27
|
+
const rows = await resource.list({}, { size: 0 });
|
|
28
|
+
for (const row of rows.items)
|
|
29
|
+
await resource.delete(row.id);
|
|
30
|
+
}
|
|
31
|
+
} });
|
|
32
|
+
const scopeKey = lifecycle.key;
|
|
24
33
|
const commits = makeRemoteCommitSource(context, options.protocols, {
|
|
25
|
-
socket: options.socket, poll: options.poll, timeout: options.timeout, stores,
|
|
34
|
+
socket: options.socket, poll: options.poll, timeout: options.timeout, stores, lifecycle,
|
|
26
35
|
});
|
|
27
36
|
const layerPlugins = () => plugins.forEach(plugin => {
|
|
28
37
|
plugin.schemas?.assigneeTypes?.forEach(registry.registerAssigneeType);
|
|
@@ -44,15 +53,14 @@ export const makePlanningClientService = (context, options) => {
|
|
|
44
53
|
return registry;
|
|
45
54
|
}
|
|
46
55
|
if (loading == null || opts?.force === true) {
|
|
47
|
-
const attempt = (async () => {
|
|
48
|
-
const bundle = await context.entrypoint(options.protocols.schema.list).call({ timeout: options.timeout });
|
|
49
|
-
|
|
50
|
-
throw new PlanningError('client:scope-changed');
|
|
56
|
+
const attempt = lifecycle.run(async (operation) => {
|
|
57
|
+
const bundle = await operation.wait(context.entrypoint(options.protocols.schema.list).call({ timeout: options.timeout, signal: operation.signal }));
|
|
58
|
+
operation.check();
|
|
51
59
|
registry.load(bundle);
|
|
52
60
|
layerPlugins();
|
|
53
61
|
loaded = true;
|
|
54
62
|
return registry;
|
|
55
|
-
})
|
|
63
|
+
});
|
|
56
64
|
loading = attempt;
|
|
57
65
|
// A failed load is forgotten, so the next caller asks again instead of inheriting the error.
|
|
58
66
|
attempt.catch(() => {
|
|
@@ -66,15 +74,26 @@ export const makePlanningClientService = (context, options) => {
|
|
|
66
74
|
// A write of data-defined schemas moves the organization's bundle too: the next `model()` reloads it.
|
|
67
75
|
const definitions = options.protocols.schema.define == null
|
|
68
76
|
? undefined
|
|
69
|
-
: makeRemoteDefinitions(context, options.protocols, {
|
|
77
|
+
: makeRemoteDefinitions(context, options.protocols, { lifecycle, timeout: options.timeout, onWrite: () => { loaded = false; loading = null; } });
|
|
70
78
|
const facadeFor = (scope) => makeRemoteFacade(context, options.protocols, { ...options.scope, ...scope }, {
|
|
71
|
-
commits, schemas: registry, loadSchemas, scopeKey, timeout: options.timeout, stores,
|
|
79
|
+
commits, schemas: registry, loadSchemas, scopeKey, lifecycle, timeout: options.timeout, stores,
|
|
72
80
|
...(definitions != null ? { definitions } : {}),
|
|
73
81
|
});
|
|
74
82
|
let fallback = null;
|
|
83
|
+
lifecycle.onInvalidate(async () => {
|
|
84
|
+
const stopping = [...feeds];
|
|
85
|
+
feeds.clear();
|
|
86
|
+
loaded = false;
|
|
87
|
+
loading = null;
|
|
88
|
+
definitions?.invalidate();
|
|
89
|
+
registry.load({ version: 1, types: [], flows: [] });
|
|
90
|
+
layerPlugins();
|
|
91
|
+
await Promise.all(stopping.map(async (feed) => await feed.stop()));
|
|
92
|
+
});
|
|
75
93
|
// Lazy, like the server's host: `context.planning()` answers before the context initializes.
|
|
76
94
|
return createLazyService(PLANNING_SERVICE, {
|
|
77
95
|
schemas: registry,
|
|
96
|
+
lifecycle,
|
|
78
97
|
scopeKey,
|
|
79
98
|
registerFeed: feed => { feeds.add(feed); return () => { feeds.delete(feed); }; },
|
|
80
99
|
commits,
|
|
@@ -99,24 +118,7 @@ export const makePlanningClientService = (context, options) => {
|
|
|
99
118
|
committed: async () => {
|
|
100
119
|
throw new PlanningUnsupported('client:committed');
|
|
101
120
|
},
|
|
102
|
-
close:
|
|
103
|
-
epoch++;
|
|
104
|
-
await Promise.all([...feeds].map(async (feed) => await feed.stop()));
|
|
105
|
-
feeds.clear();
|
|
106
|
-
await commits.close();
|
|
107
|
-
loaded = false;
|
|
108
|
-
loading = null;
|
|
109
|
-
definitions?.invalidate();
|
|
110
|
-
registry.load({ version: 1, types: [], flows: [] });
|
|
111
|
-
layerPlugins();
|
|
112
|
-
const mirrors = stores();
|
|
113
|
-
if (mirrors != null)
|
|
114
|
-
for (const resource of Object.values(mirrors)) {
|
|
115
|
-
const rows = await resource.list({}, { size: 0 });
|
|
116
|
-
for (const row of rows.items)
|
|
117
|
-
await resource.delete(row.id);
|
|
118
|
-
}
|
|
119
|
-
},
|
|
121
|
+
close: lifecycle.close,
|
|
120
122
|
...(definitions != null ? { definitions } : {}),
|
|
121
123
|
});
|
|
122
124
|
};
|
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,
|
|
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,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAC/C,OAAO,EAAE,2BAA2B,EAAE,MAAM,gBAAgB,CAAA;AAK5D;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CACvC,OAAU,EAAE,OAA8B,EACnB,EAAE;IACzB,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqC,CAAA;IAC1D,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAA;IACrC,MAAM,OAAO,GAAqB,EAAE,CAAA;IACpC,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAA;IACxD,MAAM,SAAS,GAAG,2BAA2B,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,IAAI,EAAE;YAC5F,MAAM,OAAO,GAAG,MAAM,EAAE,CAAA;YACxB,IAAI,OAAO,IAAI,IAAI;gBAAE,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;oBACnE,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;oBACjD,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,KAAK;wBAAE,MAAM,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAG,CAAC,CAAA;gBAC9D,CAAC;QACH,CAAC,EAAE,CAAC,CAAA;IACJ,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAA;IAE9B,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,EAAE,SAAS;KACxF,CAAC,CAAA;IAEF,MAAM,YAAY,GAAG,GAAS,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;QACxD,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,CAAA;QACrE,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,SAAS,GAAG,QAAQ,EAAE,CAAA;IAC1B,IAAI,MAAM,GAAG,KAAK,CAAA;IAClB,IAAI,OAAO,GAA2C,IAAI,CAAA;IAE1D,MAAM,WAAW,GAAyC,KAAK,EAAC,IAAI,EAAC,EAAE;QACrE,MAAM,GAAG,GAAG,QAAQ,EAAE,CAAA;QACtB,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;YAAC,MAAM,GAAG,KAAK,CAAC;YAAC,OAAO,GAAG,IAAI,CAAC;YAAC,WAAW,EAAE,UAAU,EAAE,CAAC;YAAC,SAAS,GAAG,GAAG,CAAA;QAAC,CAAC;QACrG,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,SAAS,CAAC,GAAG,CAAC,KAAK,EAAC,SAAS,EAAC,EAAE;gBAC9C,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAAA;gBACnJ,SAAS,CAAC,KAAK,EAAE,CAAA;gBACjB,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAA;gBACrB,YAAY,EAAE,CAAA;gBACd,MAAM,GAAG,IAAI,CAAA;gBAEb,OAAO,QAAQ,CAAA;YACjB,CAAC,CAAC,CAAA;YACF,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,SAAS,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;IAEjJ,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,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,MAAM;QAC9F,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;IAC1C,SAAS,CAAC,YAAY,CAAC,KAAK,IAAI,EAAE;QAChC,MAAM,QAAQ,GAAG,CAAC,GAAG,KAAK,CAAC,CAAA;QAC3B,KAAK,CAAC,KAAK,EAAE,CAAA;QACb,MAAM,GAAG,KAAK,CAAC;QAAC,OAAO,GAAG,IAAI,CAAC;QAAC,WAAW,EAAE,UAAU,EAAE,CAAA;QACzD,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAAC,YAAY,EAAE,CAAA;QACnE,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAC,IAAI,EAAC,EAAE,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAA;IAClE,CAAC,CAAC,CAAA;IAEF,6FAA6F;IAC7F,OAAO,iBAAiB,CAAwB,gBAAgB,EAAE;QAChE,OAAO,EAAE,QAAQ;QACjB,SAAS;QACT,QAAQ;QACR,YAAY,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,GAAG,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA,CAAC,CAAC,CAAA,CAAC,CAAC;QAE9E,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,SAAS,CAAC,KAAK;QAEtB,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"}
|
package/build/commits.d.ts
CHANGED
|
@@ -1,17 +1,6 @@
|
|
|
1
1
|
import type { BasicConfig, BasicContext } from '@owlmeans/context';
|
|
2
2
|
import { type PlanningProtocols } from '@owlmeans/planning';
|
|
3
3
|
import type { RemoteCommitSource, RemoteCommitSourceOptions } from './types.js';
|
|
4
|
-
/**
|
|
5
|
-
* The commit source of a remote facade: the `commit.get` long poll and, when the host injects a
|
|
6
|
-
* socket opener, the `commit.events` feed.
|
|
7
|
-
*
|
|
8
|
-
* `wait` SUBSCRIBES FIRST and only then reads the status — a commit landing between a read and a
|
|
9
|
-
* subscription would otherwise be missed until the deadline. It then long-polls in holds of
|
|
10
|
-
* `min(poll, remaining)` seconds, so a client with no socket (a Node connector) still learns of a
|
|
11
|
-
* commit within one round trip of it landing, and a client with one learns from whichever arrives
|
|
12
|
-
* first. The deadline is a {@link CommitTimeout}; the transition stays pending — nothing is undone.
|
|
13
|
-
*
|
|
14
|
-
* ONE socket serves every subscription of the source; releasing a subscription never closes it.
|
|
15
|
-
*/
|
|
4
|
+
/** Subscribe before reading, then race the shared socket against bounded HTTP holds. */
|
|
16
5
|
export declare const makeRemoteCommitSource: <C extends BasicConfig, T extends BasicContext<C>>(context: T, protocols: PlanningProtocols, opts?: RemoteCommitSourceOptions) => RemoteCommitSource;
|
|
17
6
|
//# sourceMappingURL=commits.d.ts.map
|
package/build/commits.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../src/commits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAA2O,KAAK,iBAAiB,EAAmC,MAAM,oBAAoB,CAAA;
|
|
1
|
+
{"version":3,"file":"commits.d.ts","sourceRoot":"","sources":["../src/commits.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAElE,OAAO,EAA2O,KAAK,iBAAiB,EAAmC,MAAM,oBAAoB,CAAA;AAKrU,OAAO,KAAK,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAA;AAM/E,wFAAwF;AACxF,eAAO,MAAM,sBAAsB,GAAI,CAAC,SAAS,WAAW,EAAE,CAAC,SAAS,YAAY,CAAC,CAAC,CAAC,WAC5E,CAAC,aAAa,iBAAiB,SAAS,yBAAyB,KACzE,kBAsMF,CAAA"}
|