@manifesto-ai/sdk 0.1.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/LICENSE +21 -0
- package/README.md +182 -0
- package/dist/__tests__/bootstrap.test.d.ts +2 -0
- package/dist/__tests__/bootstrap.test.d.ts.map +1 -0
- package/dist/__tests__/bootstrap.test.js +34 -0
- package/dist/__tests__/bootstrap.test.js.map +1 -0
- package/dist/app.d.ts +51 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +170 -0
- package/dist/app.js.map +1 -0
- package/dist/create-app.d.ts +52 -0
- package/dist/create-app.d.ts.map +1 -0
- package/dist/create-app.js +94 -0
- package/dist/create-app.js.map +1 -0
- package/dist/hooks/app-ref.d.ts +71 -0
- package/dist/hooks/app-ref.d.ts.map +1 -0
- package/dist/hooks/app-ref.js +82 -0
- package/dist/hooks/app-ref.js.map +1 -0
- package/dist/hooks/context.d.ts +22 -0
- package/dist/hooks/context.d.ts.map +1 -0
- package/dist/hooks/context.js +26 -0
- package/dist/hooks/context.js.map +1 -0
- package/dist/hooks/hookable.d.ts +79 -0
- package/dist/hooks/hookable.d.ts.map +1 -0
- package/dist/hooks/hookable.js +137 -0
- package/dist/hooks/hookable.js.map +1 -0
- package/dist/hooks/index.d.ts +14 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +13 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/queue.d.ts +57 -0
- package/dist/hooks/queue.d.ts.map +1 -0
- package/dist/hooks/queue.js +141 -0
- package/dist/hooks/queue.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.d.ts +10 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +2 -0
- package/dist/manifest.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppRef Implementation
|
|
3
|
+
*
|
|
4
|
+
* Read-only facade for hooks that prevents re-entrant mutations.
|
|
5
|
+
*
|
|
6
|
+
* @see SPEC v2.0.0 §17.2
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type { DomainSchema } from "@manifesto-ai/core";
|
|
10
|
+
import type { AppRef, AppState, AppStatus, ActOptions, Branch, ProposalId } from "@manifesto-ai/runtime";
|
|
11
|
+
import type { WorldId } from "@manifesto-ai/world";
|
|
12
|
+
import type { JobQueue } from "./queue.js";
|
|
13
|
+
/**
|
|
14
|
+
* Callbacks for AppRef operations.
|
|
15
|
+
*/
|
|
16
|
+
export interface AppRefCallbacks {
|
|
17
|
+
getStatus(): AppStatus;
|
|
18
|
+
getState<T>(): AppState<T>;
|
|
19
|
+
getDomainSchema(): DomainSchema;
|
|
20
|
+
getCurrentHead(): WorldId;
|
|
21
|
+
currentBranch(): Branch;
|
|
22
|
+
generateProposalId(): ProposalId;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* AppRefImpl: Read-only facade for hooks.
|
|
26
|
+
*
|
|
27
|
+
* HOOK-6: Hooks receive AppRef, not full App
|
|
28
|
+
* HOOK-7: enqueueAction() MUST defer execution until after hook completes
|
|
29
|
+
*
|
|
30
|
+
* @see SPEC v2.0.0 §17.2
|
|
31
|
+
*/
|
|
32
|
+
export declare class AppRefImpl implements AppRef {
|
|
33
|
+
private _callbacks;
|
|
34
|
+
private _queue;
|
|
35
|
+
private _enqueueAction;
|
|
36
|
+
constructor(callbacks: AppRefCallbacks, queue: JobQueue, enqueueAction: (proposalId: ProposalId, type: string, input?: unknown, opts?: ActOptions) => void);
|
|
37
|
+
/**
|
|
38
|
+
* Get current app status.
|
|
39
|
+
*/
|
|
40
|
+
get status(): AppStatus;
|
|
41
|
+
/**
|
|
42
|
+
* Get current state.
|
|
43
|
+
*/
|
|
44
|
+
getState<T = unknown>(): AppState<T>;
|
|
45
|
+
/**
|
|
46
|
+
* Get domain schema.
|
|
47
|
+
*/
|
|
48
|
+
getDomainSchema(): DomainSchema;
|
|
49
|
+
/**
|
|
50
|
+
* Get current head WorldId.
|
|
51
|
+
*/
|
|
52
|
+
getCurrentHead(): WorldId;
|
|
53
|
+
/**
|
|
54
|
+
* Get current branch.
|
|
55
|
+
*/
|
|
56
|
+
currentBranch(): Branch;
|
|
57
|
+
/**
|
|
58
|
+
* Enqueue an action for execution after current hook completes.
|
|
59
|
+
*
|
|
60
|
+
* HOOK-7: MUST defer execution until after current hook completes.
|
|
61
|
+
* NOT synchronous execution — prevents re-entrancy.
|
|
62
|
+
*
|
|
63
|
+
* @see SPEC v2.0.0 §17.2
|
|
64
|
+
*/
|
|
65
|
+
enqueueAction(type: string, input?: unknown, opts?: ActOptions): ProposalId;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create an AppRef with the given callbacks.
|
|
69
|
+
*/
|
|
70
|
+
export declare function createAppRef(callbacks: AppRefCallbacks, queue: JobQueue, enqueueAction: (proposalId: ProposalId, type: string, input?: unknown, opts?: ActOptions) => void): AppRef;
|
|
71
|
+
//# sourceMappingURL=app-ref.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-ref.d.ts","sourceRoot":"","sources":["../../src/hooks/app-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EACV,MAAM,EACN,QAAQ,EACR,SAAS,EACT,UAAU,EACV,MAAM,EACN,UAAU,EACX,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,SAAS,IAAI,SAAS,CAAC;IACvB,QAAQ,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3B,eAAe,IAAI,YAAY,CAAC;IAChC,cAAc,IAAI,OAAO,CAAC;IAC1B,aAAa,IAAI,MAAM,CAAC;IACxB,kBAAkB,IAAI,UAAU,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,qBAAa,UAAW,YAAW,MAAM;IACvC,OAAO,CAAC,UAAU,CAAkB;IACpC,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,cAAc,CAKZ;gBAGR,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,QAAQ,EACf,aAAa,EAAE,CACb,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,EACf,IAAI,CAAC,EAAE,UAAU,KACd,IAAI;IAOX;;OAEG;IACH,IAAI,MAAM,IAAI,SAAS,CAEtB;IAED;;OAEG;IACH,QAAQ,CAAC,CAAC,GAAG,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC;IAIpC;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;;;;;;OAOG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU;CAgB5E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,eAAe,EAC1B,KAAK,EAAE,QAAQ,EACf,aAAa,EAAE,CACb,UAAU,EAAE,UAAU,EACtB,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,OAAO,EACf,IAAI,CAAC,EAAE,UAAU,KACd,IAAI,GACR,MAAM,CAER"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AppRef Implementation
|
|
3
|
+
*
|
|
4
|
+
* Read-only facade for hooks that prevents re-entrant mutations.
|
|
5
|
+
*
|
|
6
|
+
* @see SPEC v2.0.0 §17.2
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* AppRefImpl: Read-only facade for hooks.
|
|
11
|
+
*
|
|
12
|
+
* HOOK-6: Hooks receive AppRef, not full App
|
|
13
|
+
* HOOK-7: enqueueAction() MUST defer execution until after hook completes
|
|
14
|
+
*
|
|
15
|
+
* @see SPEC v2.0.0 §17.2
|
|
16
|
+
*/
|
|
17
|
+
export class AppRefImpl {
|
|
18
|
+
_callbacks;
|
|
19
|
+
_queue;
|
|
20
|
+
_enqueueAction;
|
|
21
|
+
constructor(callbacks, queue, enqueueAction) {
|
|
22
|
+
this._callbacks = callbacks;
|
|
23
|
+
this._queue = queue;
|
|
24
|
+
this._enqueueAction = enqueueAction;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Get current app status.
|
|
28
|
+
*/
|
|
29
|
+
get status() {
|
|
30
|
+
return this._callbacks.getStatus();
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get current state.
|
|
34
|
+
*/
|
|
35
|
+
getState() {
|
|
36
|
+
return this._callbacks.getState();
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Get domain schema.
|
|
40
|
+
*/
|
|
41
|
+
getDomainSchema() {
|
|
42
|
+
return this._callbacks.getDomainSchema();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get current head WorldId.
|
|
46
|
+
*/
|
|
47
|
+
getCurrentHead() {
|
|
48
|
+
return this._callbacks.getCurrentHead();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get current branch.
|
|
52
|
+
*/
|
|
53
|
+
currentBranch() {
|
|
54
|
+
return this._callbacks.currentBranch();
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Enqueue an action for execution after current hook completes.
|
|
58
|
+
*
|
|
59
|
+
* HOOK-7: MUST defer execution until after current hook completes.
|
|
60
|
+
* NOT synchronous execution — prevents re-entrancy.
|
|
61
|
+
*
|
|
62
|
+
* @see SPEC v2.0.0 §17.2
|
|
63
|
+
*/
|
|
64
|
+
enqueueAction(type, input, opts) {
|
|
65
|
+
// Generate proposalId immediately (HANDLE-9)
|
|
66
|
+
const proposalId = this._callbacks.generateProposalId();
|
|
67
|
+
// Defer actual execution via job queue
|
|
68
|
+
this._queue.enqueue(() => {
|
|
69
|
+
// Execute action via callback (deferred)
|
|
70
|
+
this._enqueueAction(proposalId, type, input, opts);
|
|
71
|
+
}, { label: `enqueueAction:${type}:${proposalId}` });
|
|
72
|
+
// Return proposalId immediately for tracking
|
|
73
|
+
return proposalId;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Create an AppRef with the given callbacks.
|
|
78
|
+
*/
|
|
79
|
+
export function createAppRef(callbacks, queue, enqueueAction) {
|
|
80
|
+
return new AppRefImpl(callbacks, queue, enqueueAction);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=app-ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"app-ref.js","sourceRoot":"","sources":["../../src/hooks/app-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA0BH;;;;;;;GAOG;AACH,MAAM,OAAO,UAAU;IACb,UAAU,CAAkB;IAC5B,MAAM,CAAW;IACjB,cAAc,CAKZ;IAEV,YACE,SAA0B,EAC1B,KAAe,EACf,aAKS;QAET,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,IAAI,CAAC,cAAc,GAAG,aAAa,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;IACrC,CAAC;IAED;;OAEG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAK,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC;IAC3C,CAAC;IAED;;OAEG;IACH,cAAc;QACZ,OAAO,IAAI,CAAC,UAAU,CAAC,cAAc,EAAE,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACH,aAAa,CAAC,IAAY,EAAE,KAAe,EAAE,IAAiB;QAC5D,6CAA6C;QAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,kBAAkB,EAAE,CAAC;QAExD,uCAAuC;QACvC,IAAI,CAAC,MAAM,CAAC,OAAO,CACjB,GAAG,EAAE;YACH,yCAAyC;YACzC,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC,EACD,EAAE,KAAK,EAAE,iBAAiB,IAAI,IAAI,UAAU,EAAE,EAAE,CACjD,CAAC;QAEF,6CAA6C;QAC7C,OAAO,UAAU,CAAC;IACpB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,SAA0B,EAC1B,KAAe,EACf,aAKS;IAET,OAAO,IAAI,UAAU,CAAC,SAAS,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;AACzD,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook Context Implementation
|
|
3
|
+
*
|
|
4
|
+
* @see SPEC §11.2
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import type { AppRef, HookContext } from "@manifesto-ai/runtime";
|
|
8
|
+
/**
|
|
9
|
+
* Internal HookContext implementation.
|
|
10
|
+
*
|
|
11
|
+
* @see SPEC §11.2
|
|
12
|
+
*/
|
|
13
|
+
export declare class HookContextImpl implements HookContext {
|
|
14
|
+
readonly app: AppRef;
|
|
15
|
+
readonly timestamp: number;
|
|
16
|
+
constructor(app: AppRef, timestamp: number);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Create a HookContext with the given parameters.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createHookContext(app: AppRef, timestamp: number): HookContext;
|
|
22
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/hooks/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEjE;;;;GAIG;AACH,qBAAa,eAAgB,YAAW,WAAW;aAE/B,GAAG,EAAE,MAAM;aACX,SAAS,EAAE,MAAM;gBADjB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM;CAGpC;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,GAChB,WAAW,CAEb"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook Context Implementation
|
|
3
|
+
*
|
|
4
|
+
* @see SPEC §11.2
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Internal HookContext implementation.
|
|
9
|
+
*
|
|
10
|
+
* @see SPEC §11.2
|
|
11
|
+
*/
|
|
12
|
+
export class HookContextImpl {
|
|
13
|
+
app;
|
|
14
|
+
timestamp;
|
|
15
|
+
constructor(app, timestamp) {
|
|
16
|
+
this.app = app;
|
|
17
|
+
this.timestamp = timestamp;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Create a HookContext with the given parameters.
|
|
22
|
+
*/
|
|
23
|
+
export function createHookContext(app, timestamp) {
|
|
24
|
+
return new HookContextImpl(app, timestamp);
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/hooks/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH;;;;GAIG;AACH,MAAM,OAAO,eAAe;IAER;IACA;IAFlB,YACkB,GAAW,EACX,SAAiB;QADjB,QAAG,GAAH,GAAG,CAAQ;QACX,cAAS,GAAT,SAAS,CAAQ;IAEnC,CAAC;CACF;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,GAAW,EACX,SAAiB;IAEjB,OAAO,IAAI,eAAe,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hookable Implementation
|
|
3
|
+
*
|
|
4
|
+
* @see SPEC §11 Hook System
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import type { Hookable, Unsubscribe } from "@manifesto-ai/runtime";
|
|
8
|
+
import { JobQueue } from "./queue.js";
|
|
9
|
+
/**
|
|
10
|
+
* Hook execution state for mutation guard.
|
|
11
|
+
*/
|
|
12
|
+
export interface HookState {
|
|
13
|
+
/** Currently executing hook name */
|
|
14
|
+
currentHook: string | null;
|
|
15
|
+
/** Depth of nested hook calls */
|
|
16
|
+
depth: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Enhanced Hookable implementation with mutation guard.
|
|
20
|
+
*
|
|
21
|
+
* @see SPEC §11.1 Hookable interface
|
|
22
|
+
* @see SPEC §11.4 HOOK-MUT-1~4
|
|
23
|
+
*/
|
|
24
|
+
export declare class HookableImpl<TEvents> implements Hookable<TEvents> {
|
|
25
|
+
private _handlers;
|
|
26
|
+
private _hookState;
|
|
27
|
+
private _jobQueue;
|
|
28
|
+
constructor(jobQueue?: JobQueue);
|
|
29
|
+
/**
|
|
30
|
+
* Register a hook handler.
|
|
31
|
+
*
|
|
32
|
+
* @see SPEC §11.1
|
|
33
|
+
*/
|
|
34
|
+
on<K extends keyof TEvents>(name: K, fn: TEvents[K]): Unsubscribe;
|
|
35
|
+
/**
|
|
36
|
+
* Register a one-time hook handler.
|
|
37
|
+
*
|
|
38
|
+
* @see SPEC §11.1
|
|
39
|
+
*/
|
|
40
|
+
once<K extends keyof TEvents>(name: K, fn: TEvents[K]): Unsubscribe;
|
|
41
|
+
/**
|
|
42
|
+
* Emit a hook event.
|
|
43
|
+
*
|
|
44
|
+
* @see SPEC §11.4 HOOK-MUT-1~4
|
|
45
|
+
* @internal
|
|
46
|
+
*/
|
|
47
|
+
emit<K extends keyof TEvents>(name: K, ...args: any[]): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Check if currently inside a hook execution.
|
|
50
|
+
*
|
|
51
|
+
* HOOK-MUT-1: Direct mutations during hook execution are forbidden
|
|
52
|
+
*/
|
|
53
|
+
isInHook(): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* Get current hook name (if in hook).
|
|
56
|
+
*/
|
|
57
|
+
getCurrentHook(): string | null;
|
|
58
|
+
/**
|
|
59
|
+
* Assert that we are NOT in a hook.
|
|
60
|
+
* Throws HookMutationError if we are.
|
|
61
|
+
*
|
|
62
|
+
* HOOK-MUT-2: Mutation attempts during hooks throw HookMutationError
|
|
63
|
+
*
|
|
64
|
+
* @param apiName - Name of the API being called
|
|
65
|
+
* @throws HookMutationError
|
|
66
|
+
*/
|
|
67
|
+
assertNotInHook(apiName: string): void;
|
|
68
|
+
/**
|
|
69
|
+
* Get the job queue for enqueue operations.
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
getJobQueue(): JobQueue;
|
|
73
|
+
/**
|
|
74
|
+
* Get count of registered handlers for a hook.
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
handlerCount<K extends keyof TEvents>(name: K): number;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=hookable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookable.d.ts","sourceRoot":"","sources":["../../src/hooks/hookable.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAKtC;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,oCAAoC;IACpC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,qBAAa,YAAY,CAAC,OAAO,CAAE,YAAW,QAAQ,CAAC,OAAO,CAAC;IAC7D,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,SAAS,CAAW;gBAEhB,QAAQ,CAAC,EAAE,QAAQ;IAI/B;;;;OAIG;IACH,EAAE,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW;IAajE;;;;OAIG;IACH,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,WAAW;IAWnE;;;;;OAKG;IAEG,IAAI,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAmC3E;;;;OAIG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B;;;;;;;;OAQG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IAMtC;;;OAGG;IACH,WAAW,IAAI,QAAQ;IAIvB;;;OAGG;IACH,YAAY,CAAC,CAAC,SAAS,MAAM,OAAO,EAAE,IAAI,EAAE,CAAC,GAAG,MAAM;CAIvD"}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hookable Implementation
|
|
3
|
+
*
|
|
4
|
+
* @see SPEC §11 Hook System
|
|
5
|
+
* @module
|
|
6
|
+
*/
|
|
7
|
+
import { HookMutationError } from "@manifesto-ai/runtime";
|
|
8
|
+
import { JobQueue } from "./queue.js";
|
|
9
|
+
/**
|
|
10
|
+
* Enhanced Hookable implementation with mutation guard.
|
|
11
|
+
*
|
|
12
|
+
* @see SPEC §11.1 Hookable interface
|
|
13
|
+
* @see SPEC §11.4 HOOK-MUT-1~4
|
|
14
|
+
*/
|
|
15
|
+
export class HookableImpl {
|
|
16
|
+
_handlers = new Map();
|
|
17
|
+
_hookState = { currentHook: null, depth: 0 };
|
|
18
|
+
_jobQueue;
|
|
19
|
+
constructor(jobQueue) {
|
|
20
|
+
this._jobQueue = jobQueue ?? new JobQueue();
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Register a hook handler.
|
|
24
|
+
*
|
|
25
|
+
* @see SPEC §11.1
|
|
26
|
+
*/
|
|
27
|
+
on(name, fn) {
|
|
28
|
+
const key = name;
|
|
29
|
+
if (!this._handlers.has(key)) {
|
|
30
|
+
this._handlers.set(key, new Set());
|
|
31
|
+
}
|
|
32
|
+
const handlers = this._handlers.get(key);
|
|
33
|
+
handlers.add(fn);
|
|
34
|
+
return () => {
|
|
35
|
+
handlers.delete(fn);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Register a one-time hook handler.
|
|
40
|
+
*
|
|
41
|
+
* @see SPEC §11.1
|
|
42
|
+
*/
|
|
43
|
+
once(name, fn) {
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
const wrapper = ((...args) => {
|
|
46
|
+
unsub();
|
|
47
|
+
return fn(...args);
|
|
48
|
+
});
|
|
49
|
+
const unsub = this.on(name, wrapper);
|
|
50
|
+
return unsub;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Emit a hook event.
|
|
54
|
+
*
|
|
55
|
+
* @see SPEC §11.4 HOOK-MUT-1~4
|
|
56
|
+
* @internal
|
|
57
|
+
*/
|
|
58
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
59
|
+
async emit(name, ...args) {
|
|
60
|
+
const key = name;
|
|
61
|
+
const handlers = this._handlers.get(key);
|
|
62
|
+
if (!handlers || handlers.size === 0)
|
|
63
|
+
return;
|
|
64
|
+
// Track hook execution state
|
|
65
|
+
const previousHook = this._hookState.currentHook;
|
|
66
|
+
this._hookState.currentHook = key;
|
|
67
|
+
this._hookState.depth++;
|
|
68
|
+
try {
|
|
69
|
+
for (const handler of handlers) {
|
|
70
|
+
try {
|
|
71
|
+
const result = handler(...args);
|
|
72
|
+
if (result && typeof result.catch === "function") {
|
|
73
|
+
result.catch((error) => {
|
|
74
|
+
console.error(`[Hookable] Error in hook '${key}':`, error);
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(`[Hookable] Error in hook '${key}':`, error);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
finally {
|
|
84
|
+
// Restore previous state
|
|
85
|
+
this._hookState.depth--;
|
|
86
|
+
this._hookState.currentHook = previousHook;
|
|
87
|
+
// Process enqueued jobs after all hooks complete
|
|
88
|
+
if (this._hookState.depth === 0) {
|
|
89
|
+
void this._jobQueue.processAll();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Check if currently inside a hook execution.
|
|
95
|
+
*
|
|
96
|
+
* HOOK-MUT-1: Direct mutations during hook execution are forbidden
|
|
97
|
+
*/
|
|
98
|
+
isInHook() {
|
|
99
|
+
return this._hookState.depth > 0;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get current hook name (if in hook).
|
|
103
|
+
*/
|
|
104
|
+
getCurrentHook() {
|
|
105
|
+
return this._hookState.currentHook;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Assert that we are NOT in a hook.
|
|
109
|
+
* Throws HookMutationError if we are.
|
|
110
|
+
*
|
|
111
|
+
* HOOK-MUT-2: Mutation attempts during hooks throw HookMutationError
|
|
112
|
+
*
|
|
113
|
+
* @param apiName - Name of the API being called
|
|
114
|
+
* @throws HookMutationError
|
|
115
|
+
*/
|
|
116
|
+
assertNotInHook(apiName) {
|
|
117
|
+
if (this.isInHook()) {
|
|
118
|
+
throw new HookMutationError(apiName, this._hookState.currentHook);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get the job queue for enqueue operations.
|
|
123
|
+
* @internal
|
|
124
|
+
*/
|
|
125
|
+
getJobQueue() {
|
|
126
|
+
return this._jobQueue;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Get count of registered handlers for a hook.
|
|
130
|
+
* @internal
|
|
131
|
+
*/
|
|
132
|
+
handlerCount(name) {
|
|
133
|
+
const key = name;
|
|
134
|
+
return this._handlers.get(key)?.size ?? 0;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
//# sourceMappingURL=hookable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hookable.js","sourceRoot":"","sources":["../../src/hooks/hookable.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook System Module
|
|
3
|
+
*
|
|
4
|
+
* @see SPEC §11 Hook System
|
|
5
|
+
* @see SPEC v2.0.0 §17 (AppRef pattern)
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
export { HookableImpl } from "./hookable.js";
|
|
9
|
+
export type { HookState } from "./hookable.js";
|
|
10
|
+
export { JobQueue } from "./queue.js";
|
|
11
|
+
export { HookContextImpl, createHookContext } from "./context.js";
|
|
12
|
+
export { AppRefImpl, createAppRef } from "./app-ref.js";
|
|
13
|
+
export type { AppRefCallbacks } from "./app-ref.js";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE/C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGlE,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hook System Module
|
|
3
|
+
*
|
|
4
|
+
* @see SPEC §11 Hook System
|
|
5
|
+
* @see SPEC v2.0.0 §17 (AppRef pattern)
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
export { HookableImpl } from "./hookable.js";
|
|
9
|
+
export { JobQueue } from "./queue.js";
|
|
10
|
+
export { HookContextImpl, createHookContext } from "./context.js";
|
|
11
|
+
// v2.0.0 AppRef pattern
|
|
12
|
+
export { AppRefImpl, createAppRef } from "./app-ref.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAG7C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAElE,wBAAwB;AACxB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Job Queue Implementation
|
|
3
|
+
*
|
|
4
|
+
* Manages enqueued jobs with priority support.
|
|
5
|
+
*
|
|
6
|
+
* @see SPEC §11.3 ENQ-1~6
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
import type { EnqueueOptions, EnqueuedJob } from "@manifesto-ai/runtime";
|
|
10
|
+
/**
|
|
11
|
+
* Job Queue for managing enqueued jobs.
|
|
12
|
+
*
|
|
13
|
+
* @see SPEC §11.3
|
|
14
|
+
*/
|
|
15
|
+
export declare class JobQueue {
|
|
16
|
+
private _immediateJobs;
|
|
17
|
+
private _normalJobs;
|
|
18
|
+
private _deferredJobs;
|
|
19
|
+
private _isProcessing;
|
|
20
|
+
private _processScheduled;
|
|
21
|
+
/**
|
|
22
|
+
* Enqueue a job with optional priority.
|
|
23
|
+
*
|
|
24
|
+
* ENQ-1: Jobs are executed after the current hook completes
|
|
25
|
+
* ENQ-2: Priority ordering: immediate > normal > defer
|
|
26
|
+
* ENQ-3: Within same priority, FIFO ordering
|
|
27
|
+
*
|
|
28
|
+
* @see SPEC §11.3
|
|
29
|
+
*/
|
|
30
|
+
enqueue(job: EnqueuedJob, opts?: EnqueueOptions): void;
|
|
31
|
+
/**
|
|
32
|
+
* Process all pending jobs.
|
|
33
|
+
*
|
|
34
|
+
* ENQ-4: Jobs are processed in priority order
|
|
35
|
+
* ENQ-5: Errors in jobs are caught and logged (don't break queue)
|
|
36
|
+
* ENQ-6: New jobs enqueued during processing are handled
|
|
37
|
+
*
|
|
38
|
+
* @see SPEC §11.3
|
|
39
|
+
*/
|
|
40
|
+
processAll(): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Check if queue has pending jobs.
|
|
43
|
+
*/
|
|
44
|
+
hasPendingJobs(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Get count of pending jobs.
|
|
47
|
+
*/
|
|
48
|
+
pendingCount(): number;
|
|
49
|
+
/**
|
|
50
|
+
* Clear all pending jobs.
|
|
51
|
+
*/
|
|
52
|
+
clear(): void;
|
|
53
|
+
private _hasJobs;
|
|
54
|
+
private _dequeueNext;
|
|
55
|
+
private _scheduleProcess;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../../src/hooks/queue.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAYzE;;;;GAIG;AACH,qBAAa,QAAQ;IACnB,OAAO,CAAC,cAAc,CAAmB;IACzC,OAAO,CAAC,WAAW,CAAmB;IACtC,OAAO,CAAC,aAAa,CAAmB;IACxC,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,iBAAiB,CAAS;IAElC;;;;;;;;OAQG;IACH,OAAO,CAAC,GAAG,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,IAAI;IA0BtD;;;;;;;;OAQG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA8BjC;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,YAAY,IAAI,MAAM;IAQtB;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb,OAAO,CAAC,QAAQ;IAQhB,OAAO,CAAC,YAAY;IAcpB,OAAO,CAAC,gBAAgB;CAYzB"}
|