@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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +182 -0
  3. package/dist/__tests__/bootstrap.test.d.ts +2 -0
  4. package/dist/__tests__/bootstrap.test.d.ts.map +1 -0
  5. package/dist/__tests__/bootstrap.test.js +34 -0
  6. package/dist/__tests__/bootstrap.test.js.map +1 -0
  7. package/dist/app.d.ts +51 -0
  8. package/dist/app.d.ts.map +1 -0
  9. package/dist/app.js +170 -0
  10. package/dist/app.js.map +1 -0
  11. package/dist/create-app.d.ts +52 -0
  12. package/dist/create-app.d.ts.map +1 -0
  13. package/dist/create-app.js +94 -0
  14. package/dist/create-app.js.map +1 -0
  15. package/dist/hooks/app-ref.d.ts +71 -0
  16. package/dist/hooks/app-ref.d.ts.map +1 -0
  17. package/dist/hooks/app-ref.js +82 -0
  18. package/dist/hooks/app-ref.js.map +1 -0
  19. package/dist/hooks/context.d.ts +22 -0
  20. package/dist/hooks/context.d.ts.map +1 -0
  21. package/dist/hooks/context.js +26 -0
  22. package/dist/hooks/context.js.map +1 -0
  23. package/dist/hooks/hookable.d.ts +79 -0
  24. package/dist/hooks/hookable.d.ts.map +1 -0
  25. package/dist/hooks/hookable.js +137 -0
  26. package/dist/hooks/hookable.js.map +1 -0
  27. package/dist/hooks/index.d.ts +14 -0
  28. package/dist/hooks/index.d.ts.map +1 -0
  29. package/dist/hooks/index.js +13 -0
  30. package/dist/hooks/index.js.map +1 -0
  31. package/dist/hooks/queue.d.ts +57 -0
  32. package/dist/hooks/queue.d.ts.map +1 -0
  33. package/dist/hooks/queue.js +141 -0
  34. package/dist/hooks/queue.js.map +1 -0
  35. package/dist/index.d.ts +18 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +16 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/manifest.d.ts +10 -0
  40. package/dist/manifest.d.ts.map +1 -0
  41. package/dist/manifest.js +2 -0
  42. package/dist/manifest.js.map +1 -0
  43. 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"}