@process.co/element-types 0.0.17 → 0.0.19
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/define-action.test-d.d.ts +31 -0
- package/dist/define-action.test-d.d.ts.map +1 -0
- package/dist/define-action.test-d.js +48 -0
- package/dist/define-signal-app-prop.test-d.d.ts +39 -0
- package/dist/define-signal-app-prop.test-d.d.ts.map +1 -0
- package/dist/define-signal-app-prop.test-d.js +32 -0
- package/dist/define-signal-hook-this.test-d.d.ts +27 -0
- package/dist/define-signal-hook-this.test-d.d.ts.map +1 -0
- package/dist/define-signal-hook-this.test-d.js +38 -0
- package/dist/http-request-cache.d.ts +52 -0
- package/dist/http-request-cache.d.ts.map +1 -0
- package/dist/http-request-cache.js +10 -0
- package/dist/index.d.ts +256 -45
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -3
- package/package.json +1 -1
- package/src/define-action.test-d.ts +69 -0
- package/src/define-signal-app-prop.test-d.ts +44 -0
- package/src/define-signal-hook-this.test-d.ts +47 -0
- package/src/http-request-cache.ts +56 -0
- package/src/index.ts +352 -43
package/src/index.ts
CHANGED
|
@@ -21,6 +21,7 @@ import type {
|
|
|
21
21
|
ISlotStaticInstanceDefinition,
|
|
22
22
|
ISlotDefinition,
|
|
23
23
|
} from './slot-definition';
|
|
24
|
+
import { ConfigureResponseCachingOptions } from './http-request-cache';
|
|
24
25
|
|
|
25
26
|
export type { ISlotInstanceDefinition, ISlotStaticInstanceDefinition, ISlotDefinition };
|
|
26
27
|
|
|
@@ -60,6 +61,19 @@ export {
|
|
|
60
61
|
isPlatformBoundLoaderType,
|
|
61
62
|
} from './platform-loader-type';
|
|
62
63
|
|
|
64
|
+
export {
|
|
65
|
+
HTTP_REQUEST_CACHE_POLICY_KEY,
|
|
66
|
+
REPLAY_BINDING_RANGE,
|
|
67
|
+
REPLAY_META_RANGE,
|
|
68
|
+
type BodyVaryProjection,
|
|
69
|
+
type CacheVaryInfoWire,
|
|
70
|
+
type ConfigureResponseCachingOptions,
|
|
71
|
+
type DurationWire,
|
|
72
|
+
type HttpRequestCacheMode,
|
|
73
|
+
type HttpRequestCachePolicy,
|
|
74
|
+
type HttpRequestCacheVary,
|
|
75
|
+
} from './http-request-cache';
|
|
76
|
+
|
|
63
77
|
// Base types for module definitions
|
|
64
78
|
export type ModuleDefinition = {
|
|
65
79
|
type: string;
|
|
@@ -110,7 +124,7 @@ export type SignalEventShape = {
|
|
|
110
124
|
* When {@link HttpInterfaceSchemaWire.validation} is true, the runtime does **not** validate against
|
|
111
125
|
* those JSON blobs alone: it loads the ESM at {@link HttpInterfaceSchemaWire.compiledValidatorKey}
|
|
112
126
|
* (default export = Zod schema) and runs full `safeParse` on the payload via the runner-bound
|
|
113
|
-
* {@link
|
|
127
|
+
* {@link SignalRunHostServices.enforceSchema} RPC (see {@link setSignalEmitValidationHost}).
|
|
114
128
|
*/
|
|
115
129
|
export type HttpInterfaceSchemaWire = {
|
|
116
130
|
/**
|
|
@@ -141,9 +155,13 @@ export type HttpInterfaceSchemaWire = {
|
|
|
141
155
|
coerceLeafPrimitives?: boolean | 'auto';
|
|
142
156
|
};
|
|
143
157
|
|
|
144
|
-
/**
|
|
145
|
-
|
|
158
|
+
/**
|
|
159
|
+
* Host `params.$` during signal **`run`** (live webhook / test execution).
|
|
160
|
+
* Not passed to `hooks.save` — use {@link SignalSaveHookHostServices} there.
|
|
161
|
+
*/
|
|
162
|
+
export type SignalRunHostServices = {
|
|
146
163
|
export: (category: string, message: string) => void | Promise<void>;
|
|
164
|
+
|
|
147
165
|
$transitionToSlot: (slots: Array<SlotTransitionDefinition>) => void | Promise<void>;
|
|
148
166
|
|
|
149
167
|
/**
|
|
@@ -158,12 +176,30 @@ export type SignalHostServices = {
|
|
|
158
176
|
|
|
159
177
|
/**
|
|
160
178
|
* Wire for the primary `$.interface.schema` property (same persisted object the publish
|
|
161
|
-
* pipeline attaches `compiledValidatorKey` to). Use with {@link
|
|
179
|
+
* pipeline attaches `compiledValidatorKey` to). Use with {@link SignalRunHostServices.enforceSchema},
|
|
162
180
|
* e.g. `await $.enforceSchema($.interfaceEmitSchema, toEmit)`.
|
|
163
181
|
*/
|
|
164
182
|
interfaceEmitSchema?: HttpInterfaceSchemaWire;
|
|
165
183
|
};
|
|
166
184
|
|
|
185
|
+
/** @deprecated Use {@link SignalRunHostServices} for `run`; hook `$` types are separate. */
|
|
186
|
+
export type SignalHostServices = SignalRunHostServices;
|
|
187
|
+
|
|
188
|
+
/** Host `params.$` during **`hooks.save`** (publish materialization only). */
|
|
189
|
+
export type SignalSaveHookHostServices = {
|
|
190
|
+
http: {
|
|
191
|
+
configureResponseCaching: (
|
|
192
|
+
options: ConfigureResponseCachingOptions,
|
|
193
|
+
) => Promise<void> | void;
|
|
194
|
+
};
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
/** @deprecated Use {@link SignalSaveHookHostServices} */
|
|
198
|
+
export type HookSaveHostServices = SignalSaveHookHostServices;
|
|
199
|
+
|
|
200
|
+
/** Host `params.$` during `hooks.activate` / `hooks.deactivate` (no `run` or `save` surfaces). */
|
|
201
|
+
export type SignalLifecycleHookHostServices = Pick<SignalRunHostServices, 'export'>;
|
|
202
|
+
|
|
167
203
|
/** One row from a failed Zod `safeParse` (host / `validateEmitPayload`). */
|
|
168
204
|
export type SchemaValidationIssue = {
|
|
169
205
|
path: string;
|
|
@@ -193,7 +229,7 @@ export type EnforceSchemaResult<T extends unknown = unknown> =
|
|
|
193
229
|
export const PROCESS_CO_ENFORCE_SCHEMA_HOST_PAYLOAD_MARKER = 'enforceSchema' as const;
|
|
194
230
|
|
|
195
231
|
export type SignalRunOptions = {
|
|
196
|
-
$:
|
|
232
|
+
$: SignalRunHostServices;
|
|
197
233
|
event: SignalEventShape;
|
|
198
234
|
};
|
|
199
235
|
|
|
@@ -206,10 +242,10 @@ const SIGNAL_EMIT_VALIDATION_HOST = Symbol.for('process.co.signalEmitValidationH
|
|
|
206
242
|
|
|
207
243
|
/**
|
|
208
244
|
* Host shape accepted from the runner RPC bridge (`$.enforceSchema` may be typed as
|
|
209
|
-
* returning `Promise<unknown>` while {@link
|
|
245
|
+
* returning `Promise<unknown>` while {@link SignalRunHostServices} uses a generic `T`).
|
|
210
246
|
*/
|
|
211
247
|
export type SignalEmitValidationHostBinding =
|
|
212
|
-
| Pick<
|
|
248
|
+
| Pick<SignalRunHostServices, 'enforceSchema'>
|
|
213
249
|
| {
|
|
214
250
|
enforceSchema?: (
|
|
215
251
|
inputSchema: HttpInterfaceSchemaWire | undefined,
|
|
@@ -217,8 +253,8 @@ export type SignalEmitValidationHostBinding =
|
|
|
217
253
|
) => Promise<unknown>;
|
|
218
254
|
};
|
|
219
255
|
|
|
220
|
-
function getSignalEmitValidationHostBinding(): Pick<
|
|
221
|
-
return (globalThis as Record<symbol, Pick<
|
|
256
|
+
function getSignalEmitValidationHostBinding(): Pick<SignalRunHostServices, 'enforceSchema'> | undefined {
|
|
257
|
+
return (globalThis as Record<symbol, Pick<SignalRunHostServices, 'enforceSchema'> | undefined>)[
|
|
222
258
|
SIGNAL_EMIT_VALIDATION_HOST
|
|
223
259
|
];
|
|
224
260
|
}
|
|
@@ -232,11 +268,11 @@ function getSignalEmitValidationHostBinding(): Pick<SignalHostServices, 'enforce
|
|
|
232
268
|
export function setSignalEmitValidationHost(
|
|
233
269
|
host: SignalEmitValidationHostBinding | undefined,
|
|
234
270
|
): void {
|
|
235
|
-
const g = globalThis as Record<symbol, Pick<
|
|
271
|
+
const g = globalThis as Record<symbol, Pick<SignalRunHostServices, 'enforceSchema'> | undefined>;
|
|
236
272
|
if (host === undefined) {
|
|
237
273
|
delete g[SIGNAL_EMIT_VALIDATION_HOST];
|
|
238
274
|
} else {
|
|
239
|
-
g[SIGNAL_EMIT_VALIDATION_HOST] = host as Pick<
|
|
275
|
+
g[SIGNAL_EMIT_VALIDATION_HOST] = host as Pick<SignalRunHostServices, 'enforceSchema'>;
|
|
240
276
|
}
|
|
241
277
|
}
|
|
242
278
|
|
|
@@ -386,6 +422,73 @@ export type JSONValue =
|
|
|
386
422
|
| JSONValue[]
|
|
387
423
|
| { [key: string]: JSONValue; };
|
|
388
424
|
|
|
425
|
+
/**
|
|
426
|
+
* Incremental / SSE frame for {@link HttpInterfaceType.send}.
|
|
427
|
+
* Host formats SSE `event` / `id` / `data` lines; supply `data` and/or `comment` (comment-only heartbeats).
|
|
428
|
+
*/
|
|
429
|
+
export type HttpInterfaceSendPayload = {
|
|
430
|
+
event?: string;
|
|
431
|
+
id?: string;
|
|
432
|
+
data?: string | JSONValue;
|
|
433
|
+
/** SSE comment line content (`:` lines); ignored by `EventSource` default `onmessage` */
|
|
434
|
+
comment?: string;
|
|
435
|
+
};
|
|
436
|
+
|
|
437
|
+
/** Default TTFB deadline (ms) when {@link HttpInterfaceType.deferHttpResponse} omits `timeoutMs`. */
|
|
438
|
+
export const DEFAULT_DEFER_HTTP_RESPONSE_MS = 30_000;
|
|
439
|
+
|
|
440
|
+
/** Incremental stream mode selected in {@link HttpDeferResponseOptions} (at most one). */
|
|
441
|
+
export type HttpDeferredStreamMode = 'sse' | 'ndjson' | 'json-array' | 'concatenated';
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* Options for {@link HttpInterfaceType.deferHttpResponse}.
|
|
445
|
+
* Omit stream flags for a **regular** HTTP response completed later via `respond` / `redirect`.
|
|
446
|
+
* Set exactly one stream flag for incremental streaming (`send` or `append`).
|
|
447
|
+
*/
|
|
448
|
+
export type HttpDeferResponseOptions = {
|
|
449
|
+
/**
|
|
450
|
+
* When `true`, the deferred exchange is SSE (`send` / stream). When omitted or `false`, expect a normal delayed `respond` / `redirect`.
|
|
451
|
+
*/
|
|
452
|
+
sse?: boolean;
|
|
453
|
+
/**
|
|
454
|
+
* When `true`, stream newline-delimited JSON / JSON Lines (`append` + `\n` per record).
|
|
455
|
+
* See [NDJSON](https://en.wikipedia.org/wiki/JSON_streaming#Newline-delimited_JSON).
|
|
456
|
+
*/
|
|
457
|
+
ndjson?: boolean;
|
|
458
|
+
/**
|
|
459
|
+
* When `true`, stream a single JSON **array** built incrementally (`[` … comma-separated `append` … `]`).
|
|
460
|
+
* Valid `application/json` after `end`. Not the same as Wikipedia “concatenated JSON”.
|
|
461
|
+
*/
|
|
462
|
+
jsonArray?: boolean;
|
|
463
|
+
/**
|
|
464
|
+
* When `true`, stream [concatenated JSON](https://en.wikipedia.org/wiki/JSON_streaming#Concatenated_JSON):
|
|
465
|
+
* back-to-back JSON values with **no** delimiters (`{…}{…}`). Requires a streaming JSON parser on the client.
|
|
466
|
+
*/
|
|
467
|
+
concatenated?: boolean;
|
|
468
|
+
/**
|
|
469
|
+
* SSE keepalive interval (ms). Only used when `sse` is `true`. Host writes comment heartbeats by default.
|
|
470
|
+
*/
|
|
471
|
+
sseHeartbeatInterval?: number;
|
|
472
|
+
/** SSE `event:` for a single terminal frame when TTFB elapses before any output (SSE mode only) */
|
|
473
|
+
sseTimeoutEvent?: string;
|
|
474
|
+
/** JSON payload for `sseTimeoutEvent` `data:` lines; host-defined defaults if omitted (SSE mode only) */
|
|
475
|
+
sseTimeoutData?: JSONValue;
|
|
476
|
+
/** NDJSON / json-array TTFB timeout record; host defaults if omitted */
|
|
477
|
+
streamTimeoutRecord?: JSONValue;
|
|
478
|
+
};
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Periodic SSE keepalive while the stream is open; cleared on {@link HttpInterfaceType.end} or a terminal {@link HttpInterfaceType.respond}.
|
|
482
|
+
* Pass `null` to disable a previously configured heartbeat.
|
|
483
|
+
*/
|
|
484
|
+
export type HttpSseHeartbeatOptions = {
|
|
485
|
+
intervalMs: number;
|
|
486
|
+
/** When true, write comment frames (`:`) suitable for silent heartbeats */
|
|
487
|
+
asComment?: boolean;
|
|
488
|
+
event?: string;
|
|
489
|
+
data?: string | JSONValue;
|
|
490
|
+
};
|
|
491
|
+
|
|
389
492
|
export interface SendConfigHTTP {
|
|
390
493
|
method?: UppercaseHTTPMethod;
|
|
391
494
|
url: string;
|
|
@@ -596,13 +699,45 @@ type PropDefinitionInput<TType = unknown> = BasePropDefinition & {
|
|
|
596
699
|
};
|
|
597
700
|
|
|
598
701
|
export type HttpInterfaceType = {
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Full HTTP response (status / headers / body). Sending `body` completes the exchange for typical requests.
|
|
705
|
+
*/
|
|
599
706
|
respond: (response: HTTPResponse) => Promise<any> | void;
|
|
707
|
+
|
|
708
|
+
/**
|
|
709
|
+
* Incremental write or SSE frame; does not complete the exchange. Pair with {@link end} or a terminal {@link respond} where applicable.
|
|
710
|
+
*/
|
|
711
|
+
send: (payload: HttpInterfaceSendPayload) => Promise<void> | void;
|
|
600
712
|
redirect: (url: string, status?: 301 | 302) => Promise<void>;
|
|
601
|
-
|
|
713
|
+
|
|
714
|
+
/**
|
|
715
|
+
* Defer finishing the HTTP exchange until a later step completes it (or the TTFB deadline elapses).
|
|
716
|
+
* Use `options.sse` for SSE (`send`), or `ndjson` / `jsonArray` / `concatenated` for `append`, or omit for delayed `respond` / `redirect`.
|
|
717
|
+
* @param timeoutMs Time to first byte in milliseconds. Defaults to {@link DEFAULT_DEFER_HTTP_RESPONSE_MS} (30s) when omitted.
|
|
718
|
+
*/
|
|
719
|
+
deferHttpResponse: (timeoutMs?: number, options?: HttpDeferResponseOptions) => void;
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Optional runtime vary suffix (hashed and appended to the HTTP base scenario key).
|
|
723
|
+
* Call when saved `$httpRequestCachePolicy.needsRuntimeVaryKey` is true.
|
|
724
|
+
*/
|
|
725
|
+
setRequestVaryKey: (value: string) => void;
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Append one JSON value to an incremental stream (`ndjson` or `jsonArray` defer modes). Each call is one line (NDJSON) or one array element (json-array).
|
|
729
|
+
*/
|
|
730
|
+
append: (record: JSONValue) => Promise<void> | void;
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* SSE keepalive while the stream stays open. Pass `null` to disable.
|
|
734
|
+
*/
|
|
735
|
+
setSseHeartbeat: (options: HttpSseHeartbeatOptions | null) => void;
|
|
602
736
|
authenticate: (authType: HTTPAuthenticationType, options?: { token?: string }) => Promise<any> | void;
|
|
603
737
|
flow: FlowFunctions;
|
|
604
738
|
end: () => void;
|
|
605
739
|
execute: () => Promise<{ headers?: Record<string, string>;[key: string]: any }>
|
|
740
|
+
|
|
606
741
|
};
|
|
607
742
|
|
|
608
743
|
|
|
@@ -639,12 +774,32 @@ type PropTypeFromTypeValue<U, T = unknown> =
|
|
|
639
774
|
: U extends "integer" ? number
|
|
640
775
|
: U extends "$.interface.schema" ? HttpInterfaceSchemaWire
|
|
641
776
|
: U extends "$.interface.http" ? HttpInterfaceType
|
|
777
|
+
: U extends "$.interface.duration" ? import('./http-request-cache').DurationWire
|
|
778
|
+
: U extends "$.interface.cacheVaryInfo" ? import('./http-request-cache').CacheVaryInfoWire
|
|
642
779
|
: unknown;
|
|
643
780
|
|
|
781
|
+
/**
|
|
782
|
+
* Runtime shape of an embedded app prop (`props: { http: httpApp }` on a signal/action).
|
|
783
|
+
* Maps `propDefinitions` / `props` / `methods` to instance fields — not the `defineApp` module metadata (`type`, `app`, …).
|
|
784
|
+
*/
|
|
785
|
+
export type DeriveEmbeddedAppPropInstance<T extends { type: 'app' }> = Spread<
|
|
786
|
+
(T extends { propDefinitions: Record<string, any> }
|
|
787
|
+
? { [K in keyof T['propDefinitions']]: PropType<T['propDefinitions'][K]> }
|
|
788
|
+
: {}) &
|
|
789
|
+
(T extends { props: Record<string, any> }
|
|
790
|
+
? { [K in keyof T['props']]: PropType<T['props'][K]> }
|
|
791
|
+
: {}) &
|
|
792
|
+
(T extends { methods: Record<string, any> }
|
|
793
|
+
? { [K in keyof T['methods']]: T['methods'][K] }
|
|
794
|
+
: {})
|
|
795
|
+
>;
|
|
796
|
+
|
|
644
797
|
// Utility type for transforming prop definitions to their runtime types
|
|
645
798
|
export type PropType<T> =
|
|
646
|
-
// 1.
|
|
647
|
-
T extends {
|
|
799
|
+
// 1. Embedded app module → runtime prop surface (not the definition object)
|
|
800
|
+
T extends { type: 'app' }
|
|
801
|
+
? DeriveEmbeddedAppPropInstance<T>
|
|
802
|
+
: T extends { props: Record<string, any>; methods: Record<string, any> }
|
|
648
803
|
? DeriveAppInstance<T>
|
|
649
804
|
// 2. If T is a propDefinition, resolve from propDefinitions or props
|
|
650
805
|
: T extends { propDefinition: readonly [infer App, infer PropName] }
|
|
@@ -711,24 +866,69 @@ export type DeriveAppInstance<T> =
|
|
|
711
866
|
{ [K in keyof T as K extends "props" | "propDefinitions" | "methods" ? never : K]: T[K] }
|
|
712
867
|
>;
|
|
713
868
|
|
|
869
|
+
/** True when a prop definition resolves to `$.interface.http` (runtime-only on `run`). */
|
|
870
|
+
type IsHttpInterfacePropDef<P> =
|
|
871
|
+
P extends { type: '$.interface.http' }
|
|
872
|
+
? true
|
|
873
|
+
: P extends { propDefinition: readonly [infer App, infer PropName] }
|
|
874
|
+
? App extends { propDefinitions: Record<string, any> }
|
|
875
|
+
? PropName extends keyof App['propDefinitions']
|
|
876
|
+
? App['propDefinitions'][PropName] extends { type: '$.interface.http' }
|
|
877
|
+
? true
|
|
878
|
+
: false
|
|
879
|
+
: false
|
|
880
|
+
: App extends { props: Record<string, any> }
|
|
881
|
+
? PropName extends keyof App['props']
|
|
882
|
+
? App['props'][PropName] extends { type: '$.interface.http' }
|
|
883
|
+
? true
|
|
884
|
+
: false
|
|
885
|
+
: false
|
|
886
|
+
: false
|
|
887
|
+
: false;
|
|
888
|
+
|
|
714
889
|
export type DeriveSignalInstance<T> =
|
|
715
890
|
Spread<
|
|
716
|
-
Omit<T,
|
|
891
|
+
Omit<T, SignalInstanceExcludedKeys> &
|
|
717
892
|
(T extends { props: Record<string, any> }
|
|
718
|
-
? { [K in keyof T[
|
|
893
|
+
? { [K in keyof T['props']]: PropType<T['props'][K]> }
|
|
719
894
|
: {}) &
|
|
720
895
|
(T extends { propDefinitions: Record<string, any> }
|
|
721
|
-
? { [K in keyof T[
|
|
896
|
+
? { [K in keyof T['propDefinitions']]: PropType<T['propDefinitions'][K]> }
|
|
722
897
|
: {}) &
|
|
723
|
-
// Add $emit to all signal instances
|
|
724
898
|
EmitFunction &
|
|
725
899
|
(T extends { methods: Record<string, any> }
|
|
726
|
-
? { [K in keyof T[
|
|
900
|
+
? { [K in keyof T['methods']]: T['methods'][K] }
|
|
727
901
|
: {}) &
|
|
728
|
-
|
|
729
|
-
|
|
902
|
+
{
|
|
903
|
+
[K in keyof T as K extends SignalInstanceExcludedKeys ? never : K]: T[K];
|
|
904
|
+
}
|
|
730
905
|
>;
|
|
731
906
|
|
|
907
|
+
/** Module definition keys that are not instance fields on `this` in `run` or hooks. */
|
|
908
|
+
type SignalInstanceExcludedKeys =
|
|
909
|
+
| 'props'
|
|
910
|
+
| 'propDefinitions'
|
|
911
|
+
| 'methods'
|
|
912
|
+
| 'run'
|
|
913
|
+
| 'hooks';
|
|
914
|
+
|
|
915
|
+
/** Prop names on `T` that are `$.interface.http` (excluded from hook `this`). */
|
|
916
|
+
type HttpInterfacePropKeys<T> =
|
|
917
|
+
T extends { props: infer P extends Record<string, unknown> }
|
|
918
|
+
? keyof {
|
|
919
|
+
[K in keyof P as IsHttpInterfacePropDef<P[K]> extends true ? K : never]: true;
|
|
920
|
+
}
|
|
921
|
+
: never;
|
|
922
|
+
|
|
923
|
+
/**
|
|
924
|
+
* `this` inside signal hooks: instance props minus `$.interface.http` and `$emit`.
|
|
925
|
+
* Use `params.$.http.configureResponseCaching` in `save`.
|
|
926
|
+
*/
|
|
927
|
+
export type DeriveSignalHookInstance<T> = Omit<
|
|
928
|
+
DeriveSignalInstance<T>,
|
|
929
|
+
HttpInterfacePropKeys<T> | keyof EmitFunction
|
|
930
|
+
>;
|
|
931
|
+
|
|
732
932
|
// In your element-types
|
|
733
933
|
export type PropDefinitionType<App, PropName extends string> =
|
|
734
934
|
App extends { propDefinitions: Record<string, any> }
|
|
@@ -737,21 +937,37 @@ export type PropDefinitionType<App, PropName extends string> =
|
|
|
737
937
|
: unknown
|
|
738
938
|
: unknown;
|
|
739
939
|
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
940
|
+
/** Module definition keys that are not instance fields on `this` in `run`. */
|
|
941
|
+
type ActionInstanceExcludedKeys =
|
|
942
|
+
| 'props'
|
|
943
|
+
| 'propDefinitions'
|
|
944
|
+
| 'methods'
|
|
945
|
+
| 'run'
|
|
946
|
+
| 'type'
|
|
947
|
+
| 'name'
|
|
948
|
+
| 'description'
|
|
949
|
+
| 'icon'
|
|
950
|
+
| 'noAuth'
|
|
951
|
+
| 'slots'
|
|
952
|
+
| 'hasNew'
|
|
953
|
+
| 'initValue';
|
|
954
|
+
|
|
955
|
+
/** Runtime `this` for action `run` (prop values via {@link PropType}, including embedded apps). */
|
|
743
956
|
export type DeriveActionInstance<T> =
|
|
744
957
|
Spread<
|
|
745
|
-
Omit<T,
|
|
958
|
+
Omit<T, ActionInstanceExcludedKeys> &
|
|
746
959
|
(T extends { props: Record<string, any> }
|
|
747
|
-
? { [K in keyof T[
|
|
960
|
+
? { [K in keyof T['props']]: PropType<T['props'][K]> }
|
|
748
961
|
: {}) &
|
|
749
962
|
(T extends { propDefinitions: Record<string, any> }
|
|
750
|
-
? { [K in keyof T[
|
|
963
|
+
? { [K in keyof T['propDefinitions']]: PropType<T['propDefinitions'][K]> }
|
|
751
964
|
: {}) &
|
|
752
965
|
(T extends { methods: Record<string, any> }
|
|
753
|
-
? { [K in keyof T[
|
|
754
|
-
: {})
|
|
966
|
+
? { [K in keyof T['methods']]: T['methods'][K] }
|
|
967
|
+
: {}) &
|
|
968
|
+
{
|
|
969
|
+
[K in keyof T as K extends ActionInstanceExcludedKeys ? never : K]: T[K];
|
|
970
|
+
}
|
|
755
971
|
>;
|
|
756
972
|
|
|
757
973
|
// Helper type to create a module with proper this context
|
|
@@ -788,7 +1004,10 @@ export type ActionInstance<A extends Action> = DeriveActionInstance<A>;
|
|
|
788
1004
|
export type SignalInstance<S extends Signal> = DeriveSignalInstance<S>;
|
|
789
1005
|
|
|
790
1006
|
export type SignalMethod<S extends Signal> = (this: SignalInstance<S>, params: SignalRunOptions) => Promise<unknown>;
|
|
791
|
-
export type ActionMethod<A extends Action> = (
|
|
1007
|
+
export type ActionMethod<A extends Action> = (
|
|
1008
|
+
this: ActionInstance<A>,
|
|
1009
|
+
params: ActionRunOptions,
|
|
1010
|
+
) => Promise<unknown>;
|
|
792
1011
|
|
|
793
1012
|
export type PropStringDefinitionTypes = "text" | "html" | "markdown" | "json" | "xml" | "yaml" | "csv" | "tsv" | "css" | "sql" | "email" | "emailList" | "urlList" | "url" | "base64" | "javascript";
|
|
794
1013
|
|
|
@@ -815,22 +1034,112 @@ export function defineApp<const T extends object>(app: T & ThisType<DeriveAppIns
|
|
|
815
1034
|
return app;
|
|
816
1035
|
}
|
|
817
1036
|
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
{
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
1037
|
+
export type ActionRunFn = (params: ActionRunOptions) => void | Promise<unknown>;
|
|
1038
|
+
|
|
1039
|
+
/** Canonical action entrypoint — implement `run` here (see process-internal loop, etc.). */
|
|
1040
|
+
export type ActionMethodsRun = {
|
|
1041
|
+
methods: Record<string, unknown> & { run: ActionRunFn };
|
|
1042
|
+
};
|
|
1043
|
+
|
|
1044
|
+
/**
|
|
1045
|
+
* @deprecated Use `methods: { run }` instead of a top-level `run` property.
|
|
1046
|
+
* Runtime still accepts this shape via `restructureElement`.
|
|
1047
|
+
*/
|
|
1048
|
+
export type ActionMethodsLegacyTopLevelRun = {
|
|
1049
|
+
/** @deprecated Use `methods.run`. */
|
|
1050
|
+
run?: ActionRunFn;
|
|
1051
|
+
};
|
|
1052
|
+
|
|
1053
|
+
/** Minimum shape for {@link defineAction}. Prefer {@link ActionMethodsRun}. */
|
|
1054
|
+
export type ActionMethods = ActionMethodsRun | ActionMethodsLegacyTopLevelRun;
|
|
1055
|
+
|
|
1056
|
+
/** Structural requirements for an action module (tooling; prefer {@link defineAction}). */
|
|
1057
|
+
export type ActionDefinitionShape<T> = {
|
|
1058
|
+
methods: Record<string, unknown> & {
|
|
1059
|
+
run: (this: DeriveActionInstance<T>, params: ActionRunOptions) => Promise<unknown>;
|
|
1060
|
+
};
|
|
1061
|
+
/**
|
|
1062
|
+
* @deprecated Use `methods.run`.
|
|
1063
|
+
*/
|
|
1064
|
+
run?: (this: DeriveActionInstance<T>, params: ActionRunOptions) => Promise<unknown>;
|
|
1065
|
+
};
|
|
1066
|
+
|
|
1067
|
+
/** Contextual `this` for top-level and `methods.*` action functions. */
|
|
1068
|
+
export type ActionMethodsWithThis<T> = T &
|
|
1069
|
+
ThisType<DeriveActionInstance<T>> &
|
|
1070
|
+
(T extends { methods?: infer M extends Record<string, unknown> }
|
|
1071
|
+
? { methods: M & ThisType<DeriveActionInstance<T>> }
|
|
1072
|
+
: {});
|
|
1073
|
+
|
|
1074
|
+
export function defineAction<
|
|
1075
|
+
const T extends ActionMethods & { type: 'action' } & Record<string, unknown>,
|
|
1076
|
+
>(action: ActionMethodsWithThis<T>): T {
|
|
830
1077
|
return action;
|
|
831
1078
|
}
|
|
832
1079
|
|
|
833
|
-
|
|
1080
|
+
/** `params.$` for `hooks.activate` / `hooks.deactivate`. */
|
|
1081
|
+
export type SignalHostHookParameters = {
|
|
1082
|
+
$: SignalLifecycleHookHostServices;
|
|
1083
|
+
};
|
|
1084
|
+
|
|
1085
|
+
/** `params.$` for `hooks.save` — publish-only; not {@link SignalRunHostServices}. */
|
|
1086
|
+
export type SignalSaveHostParameters = {
|
|
1087
|
+
$: SignalSaveHookHostServices;
|
|
1088
|
+
};
|
|
1089
|
+
|
|
1090
|
+
export type SignalHostHookMethod<T> = (
|
|
1091
|
+
this: DeriveSignalHookInstance<T>,
|
|
1092
|
+
params: SignalHostHookParameters,
|
|
1093
|
+
) => void | Promise<void>;
|
|
1094
|
+
|
|
1095
|
+
export type SignalSaveHookMethod<T> = (
|
|
1096
|
+
this: DeriveSignalHookInstance<T>,
|
|
1097
|
+
params: SignalSaveHostParameters,
|
|
1098
|
+
) => void | Promise<void>;
|
|
1099
|
+
|
|
1100
|
+
export type SignalHooksDefinition<T> = {
|
|
1101
|
+
deactivate?: SignalHostHookMethod<T>;
|
|
1102
|
+
activate?: SignalHostHookMethod<T>;
|
|
1103
|
+
save?: SignalSaveHookMethod<T>;
|
|
1104
|
+
onDeactivate?: SignalHostHookMethod<T>;
|
|
1105
|
+
onActivate?: SignalHostHookMethod<T>;
|
|
1106
|
+
onSave?: SignalSaveHookMethod<T>;
|
|
1107
|
+
};
|
|
1108
|
+
|
|
1109
|
+
/**
|
|
1110
|
+
* Hook implementations for {@link defineSignal}: `params.$` is typed here; `this` comes from
|
|
1111
|
+
* {@link ThisType}<{@link DeriveSignalHookInstance}<T>> (avoids circular `T` and empty `this`).
|
|
1112
|
+
*/
|
|
1113
|
+
export type SignalHooksContextualDefinition = {
|
|
1114
|
+
deactivate?: (params: SignalHostHookParameters) => void | Promise<void>;
|
|
1115
|
+
activate?: (params: SignalHostHookParameters) => void | Promise<void>;
|
|
1116
|
+
save?: (params: SignalSaveHostParameters) => void | Promise<void>;
|
|
1117
|
+
onDeactivate?: (params: SignalHostHookParameters) => void | Promise<void>;
|
|
1118
|
+
onActivate?: (params: SignalHostHookParameters) => void | Promise<void>;
|
|
1119
|
+
onSave?: (params: SignalSaveHostParameters) => void | Promise<void>;
|
|
1120
|
+
};
|
|
1121
|
+
|
|
1122
|
+
/** Hook bag for {@link defineSignal}. */
|
|
1123
|
+
export type SignalHooksWithThis<T> = SignalHooksContextualDefinition &
|
|
1124
|
+
ThisType<DeriveSignalHookInstance<T>>;
|
|
1125
|
+
|
|
1126
|
+
/** Structural requirements for a signal module (used by tooling; prefer {@link defineSignal}). */
|
|
1127
|
+
export type SignalDefinitionShape<T> = {
|
|
1128
|
+
run: (this: DeriveSignalInstance<T>, params: SignalRunOptions) => Promise<unknown>;
|
|
1129
|
+
hooks?: SignalHooksDefinition<T>;
|
|
1130
|
+
};
|
|
1131
|
+
|
|
1132
|
+
/** @deprecated Use {@link defineSignal} — kept for generated lib compatibility. */
|
|
1133
|
+
export type SignalMethods = {
|
|
1134
|
+
run: (params: SignalRunOptions) => Promise<unknown>;
|
|
1135
|
+
};
|
|
1136
|
+
|
|
1137
|
+
export function defineSignal<const T extends SignalMethods & Record<string, unknown>>(
|
|
1138
|
+
signal: T &
|
|
1139
|
+
ThisType<DeriveSignalInstance<T>> & {
|
|
1140
|
+
hooks?: SignalHooksWithThis<T>;
|
|
1141
|
+
},
|
|
1142
|
+
): T {
|
|
834
1143
|
return signal;
|
|
835
1144
|
}
|
|
836
1145
|
|