@owlmeans/server-planning 0.1.18-rc.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/README.md +150 -0
- package/agent-meta/manifest.json +16 -0
- package/agent-meta/skills/server-planning/SKILL.md +203 -0
- package/build/actions/cards.d.ts +16 -0
- package/build/actions/cards.d.ts.map +1 -0
- package/build/actions/cards.js +32 -0
- package/build/actions/cards.js.map +1 -0
- package/build/actions/commit.d.ts +14 -0
- package/build/actions/commit.d.ts.map +1 -0
- package/build/actions/commit.js +48 -0
- package/build/actions/commit.js.map +1 -0
- package/build/actions/execute.d.ts +13 -0
- package/build/actions/execute.d.ts.map +1 -0
- package/build/actions/execute.js +35 -0
- package/build/actions/execute.js.map +1 -0
- package/build/actions/index.d.ts +9 -0
- package/build/actions/index.d.ts.map +1 -0
- package/build/actions/index.js +9 -0
- package/build/actions/index.js.map +1 -0
- package/build/actions/links.d.ts +5 -0
- package/build/actions/links.d.ts.map +1 -0
- package/build/actions/links.js +8 -0
- package/build/actions/links.js.map +1 -0
- package/build/actions/schemas.d.ts +6 -0
- package/build/actions/schemas.d.ts.map +1 -0
- package/build/actions/schemas.js +9 -0
- package/build/actions/schemas.js.map +1 -0
- package/build/actions/specs.d.ts +10 -0
- package/build/actions/specs.d.ts.map +1 -0
- package/build/actions/specs.js +14 -0
- package/build/actions/specs.js.map +1 -0
- package/build/actions/transitions.d.ts +6 -0
- package/build/actions/transitions.d.ts.map +1 -0
- package/build/actions/transitions.js +8 -0
- package/build/actions/transitions.js.map +1 -0
- package/build/actions/watch.d.ts +12 -0
- package/build/actions/watch.d.ts.map +1 -0
- package/build/actions/watch.js +45 -0
- package/build/actions/watch.js.map +1 -0
- package/build/consts.d.ts +18 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +19 -0
- package/build/consts.js.map +1 -0
- package/build/executor/changes.d.ts +31 -0
- package/build/executor/changes.d.ts.map +1 -0
- package/build/executor/changes.js +55 -0
- package/build/executor/changes.js.map +1 -0
- package/build/executor/code.d.ts +15 -0
- package/build/executor/code.d.ts.map +1 -0
- package/build/executor/code.js +59 -0
- package/build/executor/code.js.map +1 -0
- package/build/executor/receipt.d.ts +12 -0
- package/build/executor/receipt.d.ts.map +1 -0
- package/build/executor/receipt.js +56 -0
- package/build/executor/receipt.js.map +1 -0
- package/build/executor/resolve.d.ts +35 -0
- package/build/executor/resolve.d.ts.map +1 -0
- package/build/executor/resolve.js +136 -0
- package/build/executor/resolve.js.map +1 -0
- package/build/executor/validate.d.ts +13 -0
- package/build/executor/validate.d.ts.map +1 -0
- package/build/executor/validate.js +222 -0
- package/build/executor/validate.js.map +1 -0
- package/build/executor.d.ts +15 -0
- package/build/executor.d.ts.map +1 -0
- package/build/executor.js +113 -0
- package/build/executor.js.map +1 -0
- package/build/facade.d.ts +12 -0
- package/build/facade.d.ts.map +1 -0
- package/build/facade.js +131 -0
- package/build/facade.js.map +1 -0
- package/build/helper.d.ts +18 -0
- package/build/helper.d.ts.map +1 -0
- package/build/helper.js +32 -0
- package/build/helper.js.map +1 -0
- package/build/index.d.ts +13 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +11 -0
- package/build/index.js.map +1 -0
- package/build/projection.d.ts +28 -0
- package/build/projection.d.ts.map +1 -0
- package/build/projection.js +40 -0
- package/build/projection.js.map +1 -0
- package/build/registry.d.ts +30 -0
- package/build/registry.d.ts.map +1 -0
- package/build/registry.js +103 -0
- package/build/registry.js.map +1 -0
- package/build/service.d.ts +40 -0
- package/build/service.d.ts.map +1 -0
- package/build/service.js +109 -0
- package/build/service.js.map +1 -0
- package/build/store/commits.d.ts +15 -0
- package/build/store/commits.d.ts.map +1 -0
- package/build/store/commits.js +147 -0
- package/build/store/commits.js.map +1 -0
- package/build/store/composite.d.ts +12 -0
- package/build/store/composite.d.ts.map +1 -0
- package/build/store/composite.js +150 -0
- package/build/store/composite.js.map +1 -0
- package/build/store/fold.d.ts +39 -0
- package/build/store/fold.d.ts.map +1 -0
- package/build/store/fold.js +220 -0
- package/build/store/fold.js.map +1 -0
- package/build/store/index.d.ts +6 -0
- package/build/store/index.d.ts.map +1 -0
- package/build/store/index.js +5 -0
- package/build/store/index.js.map +1 -0
- package/build/store/memory.d.ts +19 -0
- package/build/store/memory.d.ts.map +1 -0
- package/build/store/memory.js +0 -0
- package/build/store/memory.js.map +1 -0
- package/build/store/types.d.ts +82 -0
- package/build/store/types.d.ts.map +1 -0
- package/build/store/types.js +2 -0
- package/build/store/types.js.map +1 -0
- package/build/types.d.ts +46 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/build/utils/guard.d.ts +19 -0
- package/build/utils/guard.d.ts.map +1 -0
- package/build/utils/guard.js +35 -0
- package/build/utils/guard.js.map +1 -0
- package/build/utils/index.d.ts +3 -0
- package/build/utils/index.d.ts.map +1 -0
- package/build/utils/index.js +3 -0
- package/build/utils/index.js.map +1 -0
- package/build/utils/scope.d.ts +20 -0
- package/build/utils/scope.d.ts.map +1 -0
- package/build/utils/scope.js +36 -0
- package/build/utils/scope.js.map +1 -0
- package/package.json +66 -0
- package/src/actions/cards.ts +52 -0
- package/src/actions/commit.ts +55 -0
- package/src/actions/execute.ts +47 -0
- package/src/actions/index.ts +8 -0
- package/src/actions/links.ts +14 -0
- package/src/actions/schemas.ts +15 -0
- package/src/actions/specs.ts +23 -0
- package/src/actions/transitions.ts +14 -0
- package/src/actions/watch.ts +52 -0
- package/src/consts.ts +22 -0
- package/src/executor/changes.ts +78 -0
- package/src/executor/code.ts +83 -0
- package/src/executor/receipt.ts +66 -0
- package/src/executor/resolve.ts +174 -0
- package/src/executor/validate.ts +253 -0
- package/src/executor.ts +149 -0
- package/src/facade.ts +162 -0
- package/src/helper.ts +44 -0
- package/src/index.ts +13 -0
- package/src/projection.ts +65 -0
- package/src/registry.ts +143 -0
- package/src/service.ts +157 -0
- package/src/store/commits.ts +174 -0
- package/src/store/composite.ts +171 -0
- package/src/store/fold.ts +257 -0
- package/src/store/index.ts +6 -0
- package/src/store/memory.ts +0 -0
- package/src/store/types.ts +94 -0
- package/src/types.ts +48 -0
- package/src/utils/guard.ts +40 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/scope.ts +51 -0
- package/tests/commits.spec.ts +78 -0
- package/tests/context.ts +198 -0
- package/tests/entrypoints.spec.ts +72 -0
- package/tests/executor.spec.ts +69 -0
- package/tests/memory-store.spec.ts +84 -0
- package/tests/plugins.spec.ts +86 -0
- package/tests/specifications.spec.ts +61 -0
- package/tests/tsconfig.json +17 -0
- package/tests/validation.spec.ts +62 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAE/B,cAAc,cAAc,CAAA;AAC5B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/store/index.ts"],"names":[],"mappings":"AAEA,cAAc,cAAc,CAAA;AAC5B,cAAc,gBAAgB,CAAA;AAC9B,cAAc,WAAW,CAAA;AACzB,cAAc,aAAa,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { MemoryPlanningStore, MemoryPlanningStoreOptions } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The reference `PlanningStore`, entirely in process memory.
|
|
4
|
+
*
|
|
5
|
+
* Specifications live in their own map (one record per `(parent, category)`, revised in place),
|
|
6
|
+
* cards and projects in another, relationships in a third; every read goes through the
|
|
7
|
+
* `@owlmeans/resource` in-memory query engine, so a criteria means here exactly what it means to a
|
|
8
|
+
* database store. With `sync` (the default) `project()` folds, publishes and runs the bound
|
|
9
|
+
* `committed` before it returns; with `sync: false` nothing folds until `flush()` — the shape of a
|
|
10
|
+
* queued store, for tests that need a commit to stay pending.
|
|
11
|
+
*
|
|
12
|
+
* The service binds `committed` through `bind`, which REPLACES `onCommitted`: one listener per
|
|
13
|
+
* store, so a commit runs the `after` chain once.
|
|
14
|
+
*
|
|
15
|
+
* It is wrong for anything with more than one process or a restart: the log, the cards and the
|
|
16
|
+
* commit feed are all this process's heap.
|
|
17
|
+
*/
|
|
18
|
+
export declare const makeMemoryPlanningStore: (opts?: MemoryPlanningStoreOptions) => MemoryPlanningStore;
|
|
19
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/store/memory.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAkB,mBAAmB,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AA0BjG;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,uBAAuB,UAAU,0BAA0B,KAAQ,mBA8X/E,CAAA"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/store/memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import type { CommitEvent, CommitSource, CommitStatus, PlanningStore, ProjectionStore, Relationship, RelationshipStore, SpecificationStore, Transition, TransitionStore, Workcard } from '@owlmeans/planning';
|
|
2
|
+
/** What a folding store calls for every committed transition — the service's `committed`. */
|
|
3
|
+
export interface CommitListener {
|
|
4
|
+
(event: CommitEvent): Promise<void>;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* A store the planning service can hand its `committed` to.
|
|
8
|
+
*
|
|
9
|
+
* `appendPlanningService` calls `bind` on the default store and on every plugin store it resolves,
|
|
10
|
+
* so the process that FOLDS is the process that runs the `after` chain. A store without `bind`
|
|
11
|
+
* reaches the service some other way (a durable store's projection processor looks it up on the
|
|
12
|
+
* context).
|
|
13
|
+
*/
|
|
14
|
+
export interface BindablePlanningStore extends PlanningStore {
|
|
15
|
+
bind?: (committed: CommitListener) => void;
|
|
16
|
+
}
|
|
17
|
+
export interface CommitHubOptions {
|
|
18
|
+
/** The authoritative answer for one transition, or `null` when the store has no such row. */
|
|
19
|
+
status: (transition: string) => Promise<CommitStatus | null>;
|
|
20
|
+
/** Settled events remembered for `status` after their row is gone. */
|
|
21
|
+
remember?: number;
|
|
22
|
+
/** The poll ladder `wait` climbs, in milliseconds; the last step repeats. */
|
|
23
|
+
ladder?: readonly number[];
|
|
24
|
+
}
|
|
25
|
+
/** An in-process commit fan-out: the `CommitSource` a store answers with, plus the publishing half. */
|
|
26
|
+
export interface CommitHub extends CommitSource {
|
|
27
|
+
/** Deliver an event to every matching subscriber. A listener that throws is logged, never rethrown. */
|
|
28
|
+
publish: (event: CommitEvent) => Promise<void>;
|
|
29
|
+
/** A settled event remembered by transition id, whether or not its row still exists. */
|
|
30
|
+
recall: (transition: string) => CommitEvent | undefined;
|
|
31
|
+
/** How many subscribers are attached. */
|
|
32
|
+
listeners: () => number;
|
|
33
|
+
}
|
|
34
|
+
export interface FoldOptions {
|
|
35
|
+
/** The service's `committed` — run once per committed transition, after `publish`. */
|
|
36
|
+
onCommitted?: CommitListener;
|
|
37
|
+
/** Where commit events go. Strip `record` before a cross-process bus. */
|
|
38
|
+
publish?: (event: CommitEvent) => Promise<void>;
|
|
39
|
+
now?: () => string;
|
|
40
|
+
/** The most transitions one call folds; the rest is reported as `followUp`. Unlimited when omitted. */
|
|
41
|
+
limit?: number;
|
|
42
|
+
/** Called between transitions — a queue processor renews its lock here. */
|
|
43
|
+
touch?: () => Promise<void>;
|
|
44
|
+
}
|
|
45
|
+
export interface FoldResult {
|
|
46
|
+
card: Workcard | null;
|
|
47
|
+
folded: number;
|
|
48
|
+
failed: number;
|
|
49
|
+
/** More pending transitions than `limit` allowed in one call. */
|
|
50
|
+
followUp: boolean;
|
|
51
|
+
}
|
|
52
|
+
export interface MemoryPlanningStoreSeed {
|
|
53
|
+
cards?: Workcard[];
|
|
54
|
+
links?: Relationship[];
|
|
55
|
+
transitions?: Transition[];
|
|
56
|
+
}
|
|
57
|
+
export interface MemoryPlanningStoreOptions {
|
|
58
|
+
/** Fold and publish inside `project()`. Default `true`; `false` folds only on `flush()`. */
|
|
59
|
+
sync?: boolean;
|
|
60
|
+
ids?: () => string;
|
|
61
|
+
now?: () => string;
|
|
62
|
+
seed?: MemoryPlanningStoreSeed;
|
|
63
|
+
/** The commit listener used until a service binds its own. */
|
|
64
|
+
onCommitted?: CommitListener;
|
|
65
|
+
alias?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface MemoryPlanningStore extends BindablePlanningStore {
|
|
68
|
+
transitions: TransitionStore;
|
|
69
|
+
cards: ProjectionStore;
|
|
70
|
+
specs: SpecificationStore;
|
|
71
|
+
links: RelationshipStore;
|
|
72
|
+
commits: CommitHub;
|
|
73
|
+
bind: (committed: CommitListener) => void;
|
|
74
|
+
/** Fold what is pending — for one card, or for every card with a pending transition. */
|
|
75
|
+
flush: (card?: string) => Promise<void>;
|
|
76
|
+
}
|
|
77
|
+
/** One owning route of a composite store. */
|
|
78
|
+
export interface StoreRoute {
|
|
79
|
+
owns: (type: string) => boolean;
|
|
80
|
+
store: PlanningStore;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/store/types.ts"],"names":[],"mappings":""}
|
package/build/types.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { BasicConfig, BasicContext, LazyService } from '@owlmeans/context';
|
|
2
|
+
import type { AbstractRequest } from '@owlmeans/entrypoint';
|
|
3
|
+
import type { AnyTypeSchema, PlanningPlugin, PlanningScope, PlanningService, PlanningStore, StatusFlowSchema, WithPlanningService } from '@owlmeans/planning';
|
|
4
|
+
import type { ApiServerAppend } from '@owlmeans/server-api';
|
|
5
|
+
import type { ServerConfig, ServerContext } from '@owlmeans/server-context';
|
|
6
|
+
export interface Config extends ServerConfig {
|
|
7
|
+
}
|
|
8
|
+
export interface Context<C extends Config = Config> extends ServerContext<C>, ApiServerAppend, WithPlanningService {
|
|
9
|
+
}
|
|
10
|
+
export interface PlanningServiceOptions {
|
|
11
|
+
/** The default store — every type no plugin owns. An in-memory store when omitted. */
|
|
12
|
+
store?: PlanningStore;
|
|
13
|
+
plugins?: PlanningPlugin[];
|
|
14
|
+
/** Schemas registered before any plugin's. */
|
|
15
|
+
schemas?: {
|
|
16
|
+
types?: AnyTypeSchema[];
|
|
17
|
+
flows?: StatusFlowSchema[];
|
|
18
|
+
};
|
|
19
|
+
/** Run the `after` chain in this process. Default `true`. */
|
|
20
|
+
hooks?: boolean;
|
|
21
|
+
/** Card ids when the store mints none. */
|
|
22
|
+
ids?: () => string;
|
|
23
|
+
/** ISO-8601 timestamps. */
|
|
24
|
+
now?: () => string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The registered host. Lazy on purpose: a plugin package reaches it with `ensurePlanningService`
|
|
28
|
+
* from an application's `makeContext`, before the context initializes, and `context.service()`
|
|
29
|
+
* refuses an uninitialized non-lazy service.
|
|
30
|
+
*/
|
|
31
|
+
export interface PlanningHostService extends PlanningService, LazyService {
|
|
32
|
+
}
|
|
33
|
+
/** Extra scope a deployment derives from the request — typically the write `channel`. */
|
|
34
|
+
export interface PlanningScopeExtractor {
|
|
35
|
+
(req: AbstractRequest, ctx: BasicContext<BasicConfig>): Partial<PlanningScope> | Promise<Partial<PlanningScope>>;
|
|
36
|
+
}
|
|
37
|
+
export interface PlanningHandlerOptions {
|
|
38
|
+
/** The planning service alias. `PLANNING_SERVICE` when omitted. */
|
|
39
|
+
service?: string;
|
|
40
|
+
/** The socket frame name commit events are pushed under. `PLANNING_COMMIT_EVENT` when omitted. */
|
|
41
|
+
event?: string;
|
|
42
|
+
/** The longest single long poll, in seconds — clamps `commit.get`'s `wait` and `execute`'s `timeout`. */
|
|
43
|
+
maxPoll?: number;
|
|
44
|
+
scope?: PlanningScopeExtractor;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EACV,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,gBAAgB,EAC9F,mBAAmB,EACpB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAA;AAE3E,MAAM,WAAW,MAAO,SAAQ,YAAY;CAAI;AAEhD,MAAM,WAAW,OAAO,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,CAAE,SAAQ,aAAa,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,mBAAmB;CAAI;AAEtH,MAAM,WAAW,sBAAsB;IACrC,sFAAsF;IACtF,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,OAAO,CAAC,EAAE,cAAc,EAAE,CAAA;IAC1B,8CAA8C;IAC9C,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAA;KAAE,CAAA;IACjE,6DAA6D;IAC7D,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,0CAA0C;IAC1C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;IAClB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAoB,SAAQ,eAAe,EAAE,WAAW;CAAI;AAE7E,yFAAyF;AACzF,MAAM,WAAW,sBAAsB;IACrC,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,YAAY,CAAC,WAAW,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAA;CACjH;AAED,MAAM,WAAW,sBAAsB;IACrC,mEAAmE;IACnE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,kGAAkG;IAClG,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,yGAAyG;IACzG,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,sBAAsB,CAAA;CAC/B"}
|
package/build/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { WorkcardNotFound } from '@owlmeans/planning';
|
|
2
|
+
import type { Workcard } from '@owlmeans/planning';
|
|
3
|
+
export declare const notFoundOf: (id: string) => WorkcardNotFound;
|
|
4
|
+
/**
|
|
5
|
+
* A record of another entity is absent, not forbidden.
|
|
6
|
+
*
|
|
7
|
+
* @throws {WorkcardNotFound}
|
|
8
|
+
*/
|
|
9
|
+
export declare const assertScope: <T extends Pick<Workcard, 'entityId'>>(record: T | null | undefined, scope: {
|
|
10
|
+
entityId: string;
|
|
11
|
+
}, id: string) => T;
|
|
12
|
+
/**
|
|
13
|
+
* Run a handler body so that a scope mismatch leaves as `WorkcardNotFound` — telling "not yours"
|
|
14
|
+
* apart from "does not exist" is what turns an id space into an enumeration oracle.
|
|
15
|
+
*/
|
|
16
|
+
export declare const concealed: <T>(run: () => Promise<T>) => Promise<T>;
|
|
17
|
+
/** Seconds as the wire sends them, clamped to `[0, max]`. */
|
|
18
|
+
export declare const clampSeconds: (value: unknown, max: number) => number;
|
|
19
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/utils/guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAyB,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAC5E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAElD,eAAO,MAAM,UAAU,OAAQ,MAAM,KAAG,gBAA4C,CAAA;AAEpF;;;;GAIG;AACH,eAAO,MAAM,WAAW,GAAI,CAAC,SAAS,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,UACtD,CAAC,GAAG,IAAI,GAAG,SAAS,SAAS;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,MAAM,MAAM,KACpE,CAKF,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,SAAS,GAAU,CAAC,OAAO,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAUnE,CAAA;AAED,6DAA6D;AAC7D,eAAO,MAAM,YAAY,UAAW,OAAO,OAAO,MAAM,KAAG,MAG1D,CAAA"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { PlanningScopeMismatch, WorkcardNotFound } from '@owlmeans/planning';
|
|
2
|
+
export const notFoundOf = (id) => new WorkcardNotFound(id);
|
|
3
|
+
/**
|
|
4
|
+
* A record of another entity is absent, not forbidden.
|
|
5
|
+
*
|
|
6
|
+
* @throws {WorkcardNotFound}
|
|
7
|
+
*/
|
|
8
|
+
export const assertScope = (record, scope, id) => {
|
|
9
|
+
if (record == null || record.entityId !== scope.entityId) {
|
|
10
|
+
throw notFoundOf(id);
|
|
11
|
+
}
|
|
12
|
+
return record;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Run a handler body so that a scope mismatch leaves as `WorkcardNotFound` — telling "not yours"
|
|
16
|
+
* apart from "does not exist" is what turns an id space into an enumeration oracle.
|
|
17
|
+
*/
|
|
18
|
+
export const concealed = async (run) => {
|
|
19
|
+
try {
|
|
20
|
+
return await run();
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (error instanceof PlanningScopeMismatch
|
|
24
|
+
|| error?.type === PlanningScopeMismatch.typeName) {
|
|
25
|
+
throw new WorkcardNotFound();
|
|
26
|
+
}
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
/** Seconds as the wire sends them, clamped to `[0, max]`. */
|
|
31
|
+
export const clampSeconds = (value, max) => {
|
|
32
|
+
const number = typeof value === 'number' ? value : Number(value ?? 0);
|
|
33
|
+
return Number.isFinite(number) ? Math.min(Math.max(number, 0), max) : 0;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/utils/guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAG5E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,EAAU,EAAoB,EAAE,CAAC,IAAI,gBAAgB,CAAC,EAAE,CAAC,CAAA;AAEpF;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CACzB,MAA4B,EAAE,KAA2B,EAAE,EAAU,EAClE,EAAE;IACL,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAC;QACzD,MAAM,UAAU,CAAC,EAAE,CAAC,CAAA;IACtB,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,KAAK,EAAK,GAAqB,EAAc,EAAE;IACtE,IAAI,CAAC;QACH,OAAO,MAAM,GAAG,EAAE,CAAA;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,qBAAqB;eACpC,KAAkC,EAAE,IAAI,KAAK,qBAAqB,CAAC,QAAQ,EAAE,CAAC;YAClF,MAAM,IAAI,gBAAgB,EAAE,CAAA;QAC9B,CAAC;QACD,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC,CAAA;AAED,6DAA6D;AAC7D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAc,EAAE,GAAW,EAAU,EAAE;IAClE,MAAM,MAAM,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAA;IACrE,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;AACzE,CAAC,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAA;AAC1B,cAAc,YAAY,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { BasicConfig, BasicContext } from '@owlmeans/context';
|
|
2
|
+
import type { AbstractRequest } from '@owlmeans/entrypoint';
|
|
3
|
+
import type { PlanningFacade, PlanningScope, PlanningService, TransitionActor } from '@owlmeans/planning';
|
|
4
|
+
import type { PlanningHandlerOptions } from '../types.js';
|
|
5
|
+
/** The authenticated subject of a request, as a transition names it. */
|
|
6
|
+
export declare const actorOf: (req: AbstractRequest) => TransitionActor;
|
|
7
|
+
/**
|
|
8
|
+
* The scope a request reads and writes as.
|
|
9
|
+
*
|
|
10
|
+
* `entityId` is `requireEntityKey(req)` — the resolved organization id, never a value from the
|
|
11
|
+
* body or the query — and `extra` cannot replace it; `extra` adds what the deployment derives
|
|
12
|
+
* (a `channel`, a `service`). The actor is the authenticated subject plus that channel.
|
|
13
|
+
*
|
|
14
|
+
* @throws {AuthorizationError} when the request carries no organization
|
|
15
|
+
*/
|
|
16
|
+
export declare const scopeOf: (req: AbstractRequest, extra?: Partial<PlanningScope>) => PlanningScope;
|
|
17
|
+
export declare const planningServiceOf: (ctx: BasicContext<BasicConfig>, opts?: Pick<PlanningHandlerOptions, 'service'>) => PlanningService;
|
|
18
|
+
/** The facade a handler works through: the request's scope plus what `opts.scope` derives. */
|
|
19
|
+
export declare const handlerFacade: (ctx: BasicContext<BasicConfig>, req: AbstractRequest, opts?: PlanningHandlerOptions) => Promise<PlanningFacade>;
|
|
20
|
+
//# sourceMappingURL=scope.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAE3D,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAA;AACzG,OAAO,KAAK,EAAE,sBAAsB,EAAuB,MAAM,aAAa,CAAA;AAK9E,wEAAwE;AACxE,eAAO,MAAM,OAAO,QAAS,eAAe,KAAG,eAG7C,CAAA;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,OAAO,QAAS,eAAe,UAAU,OAAO,CAAC,aAAa,CAAC,KAAG,aAY9E,CAAA;AAED,eAAO,MAAM,iBAAiB,QACvB,YAAY,CAAC,WAAW,CAAC,SAAS,IAAI,CAAC,sBAAsB,EAAE,SAAS,CAAC,KAC7E,eAAsF,CAAA;AAEzF,8FAA8F;AAC9F,eAAO,MAAM,aAAa,QACnB,YAAY,CAAC,WAAW,CAAC,OAAO,eAAe,SAAS,sBAAsB,KAClF,OAAO,CAAC,cAAc,CAIxB,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { requireEntityKey } from '@owlmeans/auth-common';
|
|
2
|
+
import { PLANNING_SERVICE } from '@owlmeans/planning';
|
|
3
|
+
const clean = (record) => Object.fromEntries(Object.entries(record).filter(([, value]) => value != null && value !== ''));
|
|
4
|
+
/** The authenticated subject of a request, as a transition names it. */
|
|
5
|
+
export const actorOf = (req) => clean({
|
|
6
|
+
profileId: req.auth?.profileId,
|
|
7
|
+
userId: req.auth?.userId,
|
|
8
|
+
});
|
|
9
|
+
/**
|
|
10
|
+
* The scope a request reads and writes as.
|
|
11
|
+
*
|
|
12
|
+
* `entityId` is `requireEntityKey(req)` — the resolved organization id, never a value from the
|
|
13
|
+
* body or the query — and `extra` cannot replace it; `extra` adds what the deployment derives
|
|
14
|
+
* (a `channel`, a `service`). The actor is the authenticated subject plus that channel.
|
|
15
|
+
*
|
|
16
|
+
* @throws {AuthorizationError} when the request carries no organization
|
|
17
|
+
*/
|
|
18
|
+
export const scopeOf = (req, extra) => {
|
|
19
|
+
const entityId = requireEntityKey(req);
|
|
20
|
+
const subject = actorOf(req);
|
|
21
|
+
const channel = extra?.channel ?? extra?.actor?.channel;
|
|
22
|
+
return clean({
|
|
23
|
+
...extra,
|
|
24
|
+
...subject,
|
|
25
|
+
entityId,
|
|
26
|
+
channel,
|
|
27
|
+
actor: clean({ ...extra?.actor, ...subject, channel }),
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
export const planningServiceOf = (ctx, opts) => ctx.service(opts?.service ?? PLANNING_SERVICE);
|
|
31
|
+
/** The facade a handler works through: the request's scope plus what `opts.scope` derives. */
|
|
32
|
+
export const handlerFacade = async (ctx, req, opts) => {
|
|
33
|
+
const extra = await opts?.scope?.(req, ctx);
|
|
34
|
+
return planningServiceOf(ctx, opts).for(scopeOf(req, extra ?? undefined));
|
|
35
|
+
};
|
|
36
|
+
//# sourceMappingURL=scope.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope.js","sourceRoot":"","sources":["../../src/utils/scope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AAGxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAIrD,MAAM,KAAK,GAAG,CAAmB,MAAS,EAAK,EAAE,CAC/C,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,IAAI,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC,CAAM,CAAA;AAEtG,wEAAwE;AACxE,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAoB,EAAmB,EAAE,CAAC,KAAK,CAAC;IACtE,SAAS,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS;IAC9B,MAAM,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM;CACzB,CAAC,CAAA;AAEF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,GAAoB,EAAE,KAA8B,EAAiB,EAAE;IAC7F,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IACtC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;IAC5B,MAAM,OAAO,GAAG,KAAK,EAAE,OAAO,IAAI,KAAK,EAAE,KAAK,EAAE,OAAO,CAAA;IAEvD,OAAO,KAAK,CAAC;QACX,GAAG,KAAK;QACR,GAAG,OAAO;QACV,QAAQ;QACR,OAAO;QACP,KAAK,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,EAAE,KAAK,EAAE,GAAG,OAAO,EAAE,OAAO,EAAE,CAAC;KACvD,CAAkB,CAAA;AACrB,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,GAA8B,EAAE,IAA8C,EAC7D,EAAE,CAAC,GAAG,CAAC,OAAO,CAAsB,IAAI,EAAE,OAAO,IAAI,gBAAgB,CAAC,CAAA;AAEzF,8FAA8F;AAC9F,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,EAChC,GAA8B,EAAE,GAAoB,EAAE,IAA6B,EAC1D,EAAE;IAC3B,MAAM,KAAK,GAAG,MAAM,IAAI,EAAE,KAAK,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IAE3C,OAAO,iBAAiB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,SAAS,CAAC,CAAC,CAAA;AAC3E,CAAC,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@owlmeans/server-planning",
|
|
3
|
+
"version": "0.1.18-rc.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "The general planning implementation — the planning service and its plugin/middleware registry, the transition executor, the in-memory store, the protocol handlers and the commit feed.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc -b",
|
|
9
|
+
"dev": "sleep 6 && nodemon -e ts,tsx,json --watch src --exec \"tsc -p ./tsconfig.json\"",
|
|
10
|
+
"watch": "tsc -b -w --preserveWatchOutput --pretty",
|
|
11
|
+
"test": "bun test ./tests"
|
|
12
|
+
},
|
|
13
|
+
"main": "build/index.js",
|
|
14
|
+
"module": "build/index.js",
|
|
15
|
+
"types": "build/index.d.ts",
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"import": "./build/index.js",
|
|
19
|
+
"require": "./build/index.js",
|
|
20
|
+
"default": "./build/index.js",
|
|
21
|
+
"module": "./build/index.js",
|
|
22
|
+
"types": "./build/index.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./store": {
|
|
25
|
+
"import": "./build/store/index.js",
|
|
26
|
+
"require": "./build/store/index.js",
|
|
27
|
+
"default": "./build/store/index.js",
|
|
28
|
+
"module": "./build/store/index.js",
|
|
29
|
+
"types": "./build/store/index.d.ts"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@owlmeans/auth": "^0.1.18-rc.26",
|
|
34
|
+
"@owlmeans/auth-common": "^0.1.18-rc.28",
|
|
35
|
+
"@owlmeans/basic-ids": "^0.1.18-rc.25",
|
|
36
|
+
"@owlmeans/context": "^0.1.18-rc.24",
|
|
37
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.27",
|
|
38
|
+
"@owlmeans/error": "^0.1.18-rc.26",
|
|
39
|
+
"@owlmeans/planning": "^0.1.18-rc.0",
|
|
40
|
+
"@owlmeans/queue": "^0.1.18-rc.22",
|
|
41
|
+
"@owlmeans/resource": "^0.1.18-rc.26",
|
|
42
|
+
"@owlmeans/route": "^0.1.18-rc.25",
|
|
43
|
+
"@owlmeans/server-api": "^0.1.18-rc.32",
|
|
44
|
+
"@owlmeans/server-context": "^0.1.18-rc.27",
|
|
45
|
+
"@owlmeans/server-entrypoint": "^0.1.18-rc.26",
|
|
46
|
+
"@owlmeans/server-socket": "^0.1.18-rc.34",
|
|
47
|
+
"@owlmeans/socket": "^0.1.18-rc.24"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"ajv": "*",
|
|
51
|
+
"ajv-formats": "*"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@owlmeans/dep-config": "workspace:*",
|
|
55
|
+
"@owlmeans/test": "^0.1.18-rc.23",
|
|
56
|
+
"@types/bun": "^1.4.0",
|
|
57
|
+
"@types/node": "^26.1.0",
|
|
58
|
+
"ajv": "^8.17.1",
|
|
59
|
+
"ajv-formats": "^3.0.1",
|
|
60
|
+
"nodemon": "^3.1.14",
|
|
61
|
+
"typescript": "^7.0.2"
|
|
62
|
+
},
|
|
63
|
+
"publishConfig": {
|
|
64
|
+
"access": "public"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { handlers } from '@owlmeans/server-api'
|
|
2
|
+
import {
|
|
3
|
+
decodeSpecificationQuery, decodeSummaryQuery, decodeTransitionQuery, decodeWorkcardQuery,
|
|
4
|
+
} from '@owlmeans/planning'
|
|
5
|
+
import type { PlanningProtocols } from '@owlmeans/planning'
|
|
6
|
+
import type { Context, PlanningHandlerOptions } from '../types.js'
|
|
7
|
+
import { concealed, handlerFacade } from '../utils/index.js'
|
|
8
|
+
|
|
9
|
+
type RequestHandler = ReturnType<ReturnType<typeof handlers<Context>>['request']>
|
|
10
|
+
|
|
11
|
+
/** Cards of the caller's entity; the query arrives in its wire shape and is decoded here. */
|
|
12
|
+
export const listCards = (protocol: PlanningProtocols['card']['list'], opts?: PlanningHandlerOptions): RequestHandler =>
|
|
13
|
+
handlers<Context>().request(protocol, async (req, ctx) => concealed(async () => {
|
|
14
|
+
const facade = await handlerFacade(ctx, req, opts)
|
|
15
|
+
|
|
16
|
+
return await facade.cards.list(decodeWorkcardQuery(req.query))
|
|
17
|
+
}))
|
|
18
|
+
|
|
19
|
+
/** Intrinsic counts of DIRECT children per parent. */
|
|
20
|
+
export const summarizeCards = (protocol: PlanningProtocols['card']['summary'], opts?: PlanningHandlerOptions): RequestHandler =>
|
|
21
|
+
handlers<Context>().request(protocol, async (req, ctx) => concealed(async () => {
|
|
22
|
+
const facade = await handlerFacade(ctx, req, opts)
|
|
23
|
+
const { parents, ...query } = decodeSummaryQuery(req.query)
|
|
24
|
+
|
|
25
|
+
return await facade.cards.summary(parents, query)
|
|
26
|
+
}))
|
|
27
|
+
|
|
28
|
+
/** @throws {WorkcardNotFound} for an absent card and for another entity's alike */
|
|
29
|
+
export const getCard = (protocol: PlanningProtocols['card']['get'], opts?: PlanningHandlerOptions): RequestHandler =>
|
|
30
|
+
handlers<Context>().request(protocol, async (req, ctx) => concealed(async () => {
|
|
31
|
+
const facade = await handlerFacade(ctx, req, opts)
|
|
32
|
+
|
|
33
|
+
return await facade.cards.get(`${req.params.id}`)
|
|
34
|
+
}))
|
|
35
|
+
|
|
36
|
+
/** One card's log. */
|
|
37
|
+
export const listCardTransitions = (protocol: PlanningProtocols['card']['transitions'], opts?: PlanningHandlerOptions): RequestHandler =>
|
|
38
|
+
handlers<Context>().request(protocol, async (req, ctx) => concealed(async () => {
|
|
39
|
+
const facade = await handlerFacade(ctx, req, opts)
|
|
40
|
+
const card = await facade.cards.get(`${req.params.id}`)
|
|
41
|
+
|
|
42
|
+
return await facade.transitions.list({ ...decodeTransitionQuery(req.query), card: card.id })
|
|
43
|
+
}))
|
|
44
|
+
|
|
45
|
+
/** One card's specifications — the current document per category unless `all`. */
|
|
46
|
+
export const listCardSpecifications = (protocol: PlanningProtocols['card']['specifications'], opts?: PlanningHandlerOptions): RequestHandler =>
|
|
47
|
+
handlers<Context>().request(protocol, async (req, ctx) => concealed(async () => {
|
|
48
|
+
const facade = await handlerFacade(ctx, req, opts)
|
|
49
|
+
const card = await facade.cards.get(`${req.params.id}`)
|
|
50
|
+
|
|
51
|
+
return await facade.specifications.list(card.id!, decodeSpecificationQuery(req.query))
|
|
52
|
+
}))
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { handlers } from '@owlmeans/server-api'
|
|
2
|
+
import { CommitState, MAX_COMMIT_POLL } from '@owlmeans/planning'
|
|
3
|
+
import type { CommitStatus, PlanningProtocols } from '@owlmeans/planning'
|
|
4
|
+
import type { Context, PlanningHandlerOptions } from '../types.js'
|
|
5
|
+
import { clampSeconds, concealed, handlerFacade } from '../utils/index.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* The poll tool: a commit's status, held open up to `wait` seconds (clamped to `maxPoll`).
|
|
9
|
+
*
|
|
10
|
+
* status → settled or no wait: answer → subscribe → poll again (a commit landing between the two
|
|
11
|
+
* reads is caught by the subscription) → race the subscription against the timer → answer the
|
|
12
|
+
* status as it is then, still `pending` when nothing landed.
|
|
13
|
+
*
|
|
14
|
+
* @throws {WorkcardNotFound} for another entity's transition
|
|
15
|
+
*/
|
|
16
|
+
export const getCommit = (
|
|
17
|
+
protocol: PlanningProtocols['commit']['get'], opts?: PlanningHandlerOptions
|
|
18
|
+
): ReturnType<ReturnType<typeof handlers<Context>>['request']> =>
|
|
19
|
+
handlers<Context>().request(protocol, async (req, ctx) => concealed(async (): Promise<CommitStatus> => {
|
|
20
|
+
const facade = await handlerFacade(ctx, req, opts)
|
|
21
|
+
const transition = `${req.params.transition}`
|
|
22
|
+
|
|
23
|
+
let status = await facade.commits.status(transition)
|
|
24
|
+
const wait = clampSeconds(req.query?.wait, opts?.maxPoll ?? MAX_COMMIT_POLL)
|
|
25
|
+
if (status.state !== CommitState.Pending || wait <= 0) {
|
|
26
|
+
return status
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
let landed = false
|
|
30
|
+
let wake: () => void = () => { landed = true }
|
|
31
|
+
const unsubscribe = await facade.commits.subscribe(event => {
|
|
32
|
+
if (event.transition === transition && event.state !== CommitState.Pending) {
|
|
33
|
+
wake()
|
|
34
|
+
}
|
|
35
|
+
})
|
|
36
|
+
try {
|
|
37
|
+
status = await facade.commits.status(transition)
|
|
38
|
+
if (status.state === CommitState.Pending) {
|
|
39
|
+
if (!landed) {
|
|
40
|
+
await new Promise<void>(resolve => {
|
|
41
|
+
const timer = setTimeout(resolve, wait * 1000)
|
|
42
|
+
wake = () => {
|
|
43
|
+
clearTimeout(timer)
|
|
44
|
+
resolve()
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
}
|
|
48
|
+
status = await facade.commits.status(transition)
|
|
49
|
+
}
|
|
50
|
+
} finally {
|
|
51
|
+
unsubscribe()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return status
|
|
55
|
+
}))
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { handlers } from '@owlmeans/server-api'
|
|
2
|
+
import { DEFAULT_COMMIT_TIMEOUT, MAX_COMMIT_POLL, TransitionAction } from '@owlmeans/planning'
|
|
3
|
+
import type {
|
|
4
|
+
ExecuteOptions, ExecuteRequest, PlanningProtocols, PlanningScope, TransitionExecution, TransitionReceiptView,
|
|
5
|
+
} from '@owlmeans/planning'
|
|
6
|
+
import type { Context, PlanningHandlerOptions } from '../types.js'
|
|
7
|
+
import { concealed, handlerFacade } from '../utils/index.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* What a wire execution may say. `actor` is dropped — the scope names the writer — and a create's
|
|
11
|
+
* `createdBy` is the authenticated subject, whatever the body claimed.
|
|
12
|
+
*/
|
|
13
|
+
export const wireExecution = (body: ExecuteRequest, scope: PlanningScope): TransitionExecution => {
|
|
14
|
+
const { wait: _wait, timeout: _timeout, actor: _actor, ...exec } = body
|
|
15
|
+
if (exec.action === TransitionAction.Create && exec.card != null && typeof exec.card === 'object') {
|
|
16
|
+
const { createdBy: _createdBy, ...draft } = exec.card
|
|
17
|
+
const subject = scope.profileId ?? scope.userId
|
|
18
|
+
exec.card = subject != null ? { ...draft, createdBy: subject } : draft
|
|
19
|
+
}
|
|
20
|
+
return exec
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** `wait`/`timeout` as a server grants them: the timeout never holds a request past `maxPoll`. */
|
|
24
|
+
export const executeOptionsOf = (body: Pick<ExecuteRequest, 'wait' | 'timeout'>, maxPoll: number): ExecuteOptions => {
|
|
25
|
+
const ceiling = maxPoll * 1000
|
|
26
|
+
if (body.wait !== true) {
|
|
27
|
+
return {}
|
|
28
|
+
}
|
|
29
|
+
const asked = Number(body.timeout ?? DEFAULT_COMMIT_TIMEOUT)
|
|
30
|
+
return { wait: true, timeout: Math.min(Number.isFinite(asked) && asked > 0 ? asked : DEFAULT_COMMIT_TIMEOUT, ceiling) }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** The one write route. */
|
|
34
|
+
export const executePlanning = (
|
|
35
|
+
protocol: PlanningProtocols['execute'], opts?: PlanningHandlerOptions
|
|
36
|
+
): ReturnType<ReturnType<typeof handlers<Context>>['request']> =>
|
|
37
|
+
handlers<Context>().request(protocol, async (req, ctx) => concealed(async (): Promise<TransitionReceiptView> => {
|
|
38
|
+
const facade = await handlerFacade(ctx, req, opts)
|
|
39
|
+
const body = (req.body ?? {}) as ExecuteRequest
|
|
40
|
+
const receipt = await facade.execute(
|
|
41
|
+
wireExecution(body, facade.scope), executeOptionsOf(body, opts?.maxPoll ?? MAX_COMMIT_POLL)
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
return receipt.card !== undefined
|
|
45
|
+
? { transition: receipt.transition, card: receipt.card }
|
|
46
|
+
: { transition: receipt.transition }
|
|
47
|
+
}))
|