@quazardous/quarkernel 2.2.5 → 2.3.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/dist/{create-machine-CYsscHPX.d.cts → create-machine-SGkCnU0g.d.cts} +33 -1
- package/dist/{create-machine-CYsscHPX.d.ts → create-machine-SGkCnU0g.d.ts} +33 -1
- package/dist/fsm.cjs +100 -0
- package/dist/fsm.cjs.map +1 -1
- package/dist/fsm.d.cts +2 -2
- package/dist/fsm.d.ts +2 -2
- package/dist/fsm.js +100 -0
- package/dist/fsm.js.map +1 -1
- package/dist/{index-BDf1xZi6.d.cts → index-0UbjHkkt.d.ts} +62 -4
- package/dist/{index-BPMXiW32.d.ts → index-KSnUuM2s.d.cts} +62 -4
- package/dist/index.cjs +100 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +100 -0
- package/dist/index.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/dist/xstate.d.cts +1 -1
- package/dist/xstate.d.ts +1 -1
- package/package.json +1 -1
|
@@ -113,8 +113,40 @@ interface Machine<TContext = any> {
|
|
|
113
113
|
getContext(): TContext;
|
|
114
114
|
/** Update context */
|
|
115
115
|
setContext(updater: Partial<TContext> | ((ctx: TContext) => TContext)): void;
|
|
116
|
-
/**
|
|
116
|
+
/**
|
|
117
|
+
* Send transition event
|
|
118
|
+
*
|
|
119
|
+
* @returns Promise<boolean> - true if transition occurred, false otherwise
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const transitioned = await machine.send('SUBMIT');
|
|
124
|
+
* // After await, check machine.getState() for current state
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
117
127
|
send(event: TransitionEvent, payload?: any, options?: SendOptions<TContext>): Promise<boolean>;
|
|
128
|
+
/**
|
|
129
|
+
* Wait until machine reaches a specific state
|
|
130
|
+
*
|
|
131
|
+
* @param state - Target state to wait for
|
|
132
|
+
* @param options - Optional timeout
|
|
133
|
+
* @returns Promise resolving when state is reached
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* // .then() receives: { state, from?, event?, context }
|
|
138
|
+
* await machine.waitFor('completed');
|
|
139
|
+
* await machine.waitFor('completed', { timeout: 5000 });
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
waitFor(state: StateName, options?: {
|
|
143
|
+
timeout?: number;
|
|
144
|
+
}): Promise<{
|
|
145
|
+
state: StateName;
|
|
146
|
+
from?: StateName;
|
|
147
|
+
event?: TransitionEvent;
|
|
148
|
+
context: TContext;
|
|
149
|
+
}>;
|
|
118
150
|
/** Check if transition is valid from current state */
|
|
119
151
|
can(event: TransitionEvent): boolean;
|
|
120
152
|
/** Get available transitions from current state */
|
|
@@ -113,8 +113,40 @@ interface Machine<TContext = any> {
|
|
|
113
113
|
getContext(): TContext;
|
|
114
114
|
/** Update context */
|
|
115
115
|
setContext(updater: Partial<TContext> | ((ctx: TContext) => TContext)): void;
|
|
116
|
-
/**
|
|
116
|
+
/**
|
|
117
|
+
* Send transition event
|
|
118
|
+
*
|
|
119
|
+
* @returns Promise<boolean> - true if transition occurred, false otherwise
|
|
120
|
+
*
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* const transitioned = await machine.send('SUBMIT');
|
|
124
|
+
* // After await, check machine.getState() for current state
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
117
127
|
send(event: TransitionEvent, payload?: any, options?: SendOptions<TContext>): Promise<boolean>;
|
|
128
|
+
/**
|
|
129
|
+
* Wait until machine reaches a specific state
|
|
130
|
+
*
|
|
131
|
+
* @param state - Target state to wait for
|
|
132
|
+
* @param options - Optional timeout
|
|
133
|
+
* @returns Promise resolving when state is reached
|
|
134
|
+
*
|
|
135
|
+
* @example
|
|
136
|
+
* ```typescript
|
|
137
|
+
* // .then() receives: { state, from?, event?, context }
|
|
138
|
+
* await machine.waitFor('completed');
|
|
139
|
+
* await machine.waitFor('completed', { timeout: 5000 });
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
waitFor(state: StateName, options?: {
|
|
143
|
+
timeout?: number;
|
|
144
|
+
}): Promise<{
|
|
145
|
+
state: StateName;
|
|
146
|
+
from?: StateName;
|
|
147
|
+
event?: TransitionEvent;
|
|
148
|
+
context: TContext;
|
|
149
|
+
}>;
|
|
118
150
|
/** Check if transition is valid from current state */
|
|
119
151
|
can(event: TransitionEvent): boolean;
|
|
120
152
|
/** Get available transitions from current state */
|
package/dist/fsm.cjs
CHANGED
|
@@ -460,6 +460,39 @@ var Composition = class {
|
|
|
460
460
|
onComposed(listener, options) {
|
|
461
461
|
return this.kernel.on(COMPOSED_EVENT, listener, options);
|
|
462
462
|
}
|
|
463
|
+
/**
|
|
464
|
+
* Wait for the next composition completion as a Promise
|
|
465
|
+
*
|
|
466
|
+
* @param options - Optional timeout configuration
|
|
467
|
+
* @returns Promise resolving with composed event data
|
|
468
|
+
*
|
|
469
|
+
* @example
|
|
470
|
+
* ```typescript
|
|
471
|
+
* // .then() receives: { sources, contexts, merged }
|
|
472
|
+
* const result = await composition.once();
|
|
473
|
+
* console.log(result.data.merged); // merged context from all sources
|
|
474
|
+
* console.log(result.data.sources); // ['event1', 'event2']
|
|
475
|
+
*
|
|
476
|
+
* // With timeout
|
|
477
|
+
* const result = await composition.once({ timeout: 5000 });
|
|
478
|
+
* ```
|
|
479
|
+
*/
|
|
480
|
+
once(options) {
|
|
481
|
+
return new Promise((resolve, reject) => {
|
|
482
|
+
let timeoutId;
|
|
483
|
+
const listener = (event) => {
|
|
484
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
485
|
+
resolve(event);
|
|
486
|
+
};
|
|
487
|
+
const unbind = this.kernel.on(COMPOSED_EVENT, listener, { once: true });
|
|
488
|
+
if (options?.timeout) {
|
|
489
|
+
timeoutId = setTimeout(() => {
|
|
490
|
+
unbind();
|
|
491
|
+
reject(new Error(`composition.once() timed out after ${options.timeout}ms`));
|
|
492
|
+
}, options.timeout);
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
}
|
|
463
496
|
/**
|
|
464
497
|
* Remove a listener for composed events
|
|
465
498
|
*/
|
|
@@ -711,6 +744,42 @@ var Kernel = class _Kernel {
|
|
|
711
744
|
}
|
|
712
745
|
return () => this.off(event, listener);
|
|
713
746
|
}
|
|
747
|
+
/**
|
|
748
|
+
* Wait for an event once (Promise-based)
|
|
749
|
+
*
|
|
750
|
+
* For callback style, use: `qk.on(event, listener, { once: true })`
|
|
751
|
+
*
|
|
752
|
+
* @param eventName - Event to wait for
|
|
753
|
+
* @param options - Optional timeout in ms
|
|
754
|
+
* @returns Promise resolving with the event
|
|
755
|
+
*
|
|
756
|
+
* @example
|
|
757
|
+
* ```typescript
|
|
758
|
+
* // .then() receives: IKernelEvent { name, data, context, timestamp }
|
|
759
|
+
* const event = await qk.once('user:loaded');
|
|
760
|
+
* console.log(event.data); // event payload
|
|
761
|
+
* console.log(event.context); // shared context
|
|
762
|
+
*
|
|
763
|
+
* // With timeout (rejects if event doesn't fire)
|
|
764
|
+
* const event = await qk.once('user:loaded', { timeout: 5000 });
|
|
765
|
+
* ```
|
|
766
|
+
*/
|
|
767
|
+
once(eventName, options) {
|
|
768
|
+
return new Promise((resolve, reject) => {
|
|
769
|
+
let timeoutId;
|
|
770
|
+
const listener = (event) => {
|
|
771
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
772
|
+
resolve(event);
|
|
773
|
+
};
|
|
774
|
+
const unbind = this.on(eventName, listener, { once: true });
|
|
775
|
+
if (options?.timeout) {
|
|
776
|
+
timeoutId = setTimeout(() => {
|
|
777
|
+
unbind();
|
|
778
|
+
reject(new Error(`once('${String(eventName)}') timed out after ${options.timeout}ms`));
|
|
779
|
+
}, options.timeout);
|
|
780
|
+
}
|
|
781
|
+
});
|
|
782
|
+
}
|
|
714
783
|
/**
|
|
715
784
|
* Remove an event listener
|
|
716
785
|
* If no listener provided, removes all listeners for the event
|
|
@@ -1310,6 +1379,37 @@ function useMachine(kernel, config) {
|
|
|
1310
1379
|
history = [...snapshot2.history];
|
|
1311
1380
|
}
|
|
1312
1381
|
},
|
|
1382
|
+
waitFor(targetState, options) {
|
|
1383
|
+
if (currentState === targetState) {
|
|
1384
|
+
return Promise.resolve({
|
|
1385
|
+
state: currentState,
|
|
1386
|
+
context: structuredClone(context)
|
|
1387
|
+
});
|
|
1388
|
+
}
|
|
1389
|
+
return new Promise((resolve, reject) => {
|
|
1390
|
+
let timeoutId;
|
|
1391
|
+
const unbind = kernel.on(
|
|
1392
|
+
`${prefix}:enter:${targetState}`,
|
|
1393
|
+
(event) => {
|
|
1394
|
+
if (timeoutId) clearTimeout(timeoutId);
|
|
1395
|
+
unbind();
|
|
1396
|
+
resolve({
|
|
1397
|
+
state: targetState,
|
|
1398
|
+
from: event.data?.from,
|
|
1399
|
+
event: event.data?.event,
|
|
1400
|
+
context: structuredClone(context)
|
|
1401
|
+
});
|
|
1402
|
+
}
|
|
1403
|
+
);
|
|
1404
|
+
cleanupFns.push(unbind);
|
|
1405
|
+
if (options?.timeout) {
|
|
1406
|
+
timeoutId = setTimeout(() => {
|
|
1407
|
+
unbind();
|
|
1408
|
+
reject(new Error(`waitFor('${targetState}') timed out after ${options.timeout}ms`));
|
|
1409
|
+
}, options.timeout);
|
|
1410
|
+
}
|
|
1411
|
+
});
|
|
1412
|
+
},
|
|
1313
1413
|
destroy() {
|
|
1314
1414
|
for (const cleanup of cleanupFns) {
|
|
1315
1415
|
cleanup();
|