webspresso 0.0.110 → 0.0.112

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/index.d.ts CHANGED
@@ -6421,11 +6421,16 @@ export interface AppApiRouteMap {
6421
6421
  DELETE: Record<string, { input: any; response: any }>;
6422
6422
  }
6423
6423
 
6424
+ export type ClientRefetchPolicy = boolean | 'always';
6425
+
6424
6426
  export interface ClientTask<TData = any, TArgs extends unknown[] = any[]> {
6425
6427
  readonly pending: boolean;
6426
6428
  readonly data: TData | null;
6427
6429
  readonly error: ClientRequestError | Error | null;
6428
6430
  readonly stale: boolean;
6431
+ readonly lastUpdatedAt: number;
6432
+ readonly lastArgs: TArgs;
6433
+ isStale(): boolean;
6429
6434
  run(...args: TArgs): Promise<TData | undefined>;
6430
6435
  cancel(): void;
6431
6436
  dispose(): void;
@@ -6435,6 +6440,14 @@ export interface ClientTaskOptions {
6435
6440
  concurrency?: ClientConcurrencyPolicy;
6436
6441
  policy?: ClientConcurrencyPolicy;
6437
6442
  key?: string;
6443
+ staleTime?: number | string;
6444
+ refetchOnMount?: ClientRefetchPolicy;
6445
+ refetchOnVisit?: ClientRefetchPolicy;
6446
+ refetchOnWindowFocus?: ClientRefetchPolicy;
6447
+ refetchOnFocus?: ClientRefetchPolicy;
6448
+ refetchOnReconnect?: ClientRefetchPolicy;
6449
+ refetchInterval?: number | string | false;
6450
+ refetchIntervalInBackground?: boolean;
6438
6451
  }
6439
6452
 
6440
6453
  export interface ClientFormFillOptions {
@@ -6533,25 +6546,204 @@ export interface ControllerPersistConfig<TState extends Record<string, any> = Re
6533
6546
  debounce?: number;
6534
6547
  }
6535
6548
 
6549
+ export interface AppClientServices {}
6550
+
6551
+ export interface ClientServiceMountHostOptions {
6552
+ key?: string;
6553
+ name?: string;
6554
+ target?: HTMLElement | null;
6555
+ selector?: string;
6556
+ container?: HTMLElement | null;
6557
+ root?: Document | HTMLElement | null;
6558
+ tagName?: string;
6559
+ id?: string;
6560
+ className?: string;
6561
+ attributes?: Record<string, string | number | boolean | null | undefined>;
6562
+ createOnly?: boolean;
6563
+ clearOnUnmount?: boolean;
6564
+ }
6565
+
6566
+ export interface ClientServiceHostHandle {
6567
+ readonly key: string;
6568
+ readonly el: ControllerElement;
6569
+ readonly created: boolean;
6570
+ readonly mounted: boolean;
6571
+ clear(): void;
6572
+ onUnmount(cleanupFn: (el: ControllerElement) => void): () => void;
6573
+ unmount(): void;
6574
+ destroy(): void;
6575
+ }
6576
+
6577
+ export interface ClientServiceHostHelper {
6578
+ mount(keyOrOptions?: string | ClientServiceMountHostOptions, options?: ClientServiceMountHostOptions): ClientServiceHostHandle;
6579
+ get(key?: string): ClientServiceHostHandle | null;
6580
+ has(key?: string): boolean;
6581
+ unmount(key?: string): boolean;
6582
+ }
6583
+
6584
+ export interface ClientServiceContext<TServices = AppClientServices> {
6585
+ readonly name: string;
6586
+ readonly api: ClientApiClient;
6587
+ readonly storage: ClientStorage & { readonly global: ClientStorage; readonly root: ClientStorage };
6588
+ readonly signal: AbortSignal;
6589
+ readonly root: Document | HTMLElement | null;
6590
+ readonly runtime: ClientRuntime<TServices> | null;
6591
+ readonly services: ClientServicesRegistry<TServices>;
6592
+ readonly host: ClientServiceHostHelper;
6593
+ mountHost(keyOrOptions?: string | ClientServiceMountHostOptions, options?: ClientServiceMountHostOptions): ClientServiceHostHandle;
6594
+ onCleanup(cleanupFn: () => void): () => void;
6595
+ onDispose(cleanupFn: () => void): () => void;
6596
+ isDisposed(): boolean;
6597
+ }
6598
+
6599
+ export interface ClientServiceDefinition<TService = any> {
6600
+ readonly __isWebspressoClientService: true;
6601
+ readonly __serviceType?: TService;
6602
+ readonly name: string | null;
6603
+ readonly load: ((ctx: ClientServiceContext) => Promise<any> | any) | null;
6604
+ readonly create: ((ctx: ClientServiceContext, loaded?: any) => Promise<TService> | TService) | null;
6605
+ readonly dispose: ((instance: TService, ctx: ClientServiceContext) => void | Promise<void>) | null;
6606
+ }
6607
+
6608
+ export type InferClientServiceExport<T> =
6609
+ T extends ClientServiceDefinition<infer S>
6610
+ ? S
6611
+ : T extends (...args: any[]) => infer R
6612
+ ? Awaited<R> extends ClientServiceDefinition<infer S>
6613
+ ? S
6614
+ : Awaited<R>
6615
+ : T extends { createService: (...args: any[]) => infer R }
6616
+ ? Awaited<R>
6617
+ : T extends { setup: (...args: any[]) => infer R }
6618
+ ? Awaited<R>
6619
+ : T extends { create: (...args: any[]) => infer R }
6620
+ ? Awaited<R>
6621
+ : T;
6622
+
6623
+ export type InferClientService<T> =
6624
+ T extends ClientServiceDefinition<infer S>
6625
+ ? S
6626
+ : T extends { default: infer D }
6627
+ ? InferClientServiceExport<D>
6628
+ : InferClientServiceExport<T>;
6629
+
6630
+ export type InferClientServicesMap<TMap> = {
6631
+ [K in keyof TMap]: InferClientService<TMap[K]>;
6632
+ };
6633
+
6634
+ export type ResolvedClientServicesMap<TServices = AppClientServices> =
6635
+ [keyof TServices] extends [never]
6636
+ ? AppClientServices
6637
+ : InferClientServicesMap<TServices>;
6638
+
6639
+ export type ClientServiceKey<TServices = AppClientServices> =
6640
+ [keyof ResolvedClientServicesMap<TServices>] extends [never]
6641
+ ? string
6642
+ : keyof ResolvedClientServicesMap<TServices> & string;
6643
+
6644
+ export interface ClientServicesRegistry<TServices = AppClientServices> {
6645
+ get<K extends ClientServiceKey<TServices>>(
6646
+ name: K
6647
+ ): Promise<
6648
+ K extends keyof ResolvedClientServicesMap<TServices>
6649
+ ? ResolvedClientServicesMap<TServices>[K]
6650
+ : any
6651
+ >;
6652
+ has(name: string): boolean;
6653
+ isInitialized(name: string): boolean;
6654
+ peek<K extends ClientServiceKey<TServices>>(
6655
+ name: K
6656
+ ): K extends keyof ResolvedClientServicesMap<TServices>
6657
+ ? ResolvedClientServicesMap<TServices>[K] | undefined
6658
+ : any;
6659
+ register<TDef>(name: string, definition: TDef): ClientServiceDefinition<InferClientService<TDef>>;
6660
+ registerAll(services: Record<string, unknown>): void;
6661
+ dispose(): void;
6662
+ destroy(): void;
6663
+ readonly isDisposed: boolean;
6664
+ }
6665
+
6666
+ export function defineClientService<TLoaded, TService>(definition: {
6667
+ name?: string;
6668
+ load: (ctx: ClientServiceContext) => Promise<TLoaded> | TLoaded;
6669
+ create: (ctx: ClientServiceContext, loaded: TLoaded) => Promise<TService> | TService;
6670
+ dispose?: (instance: TService, ctx: ClientServiceContext) => void | Promise<void>;
6671
+ }): ClientServiceDefinition<TService>;
6672
+
6673
+ export function defineClientService<TLoaded>(definition: {
6674
+ name?: string;
6675
+ load: (ctx: ClientServiceContext) => Promise<TLoaded> | TLoaded;
6676
+ dispose?: (instance: InferClientService<TLoaded>, ctx: ClientServiceContext) => void | Promise<void>;
6677
+ }): ClientServiceDefinition<InferClientService<TLoaded>>;
6678
+
6679
+ export function defineClientService<TService>(definition: {
6680
+ name?: string;
6681
+ create: (ctx: ClientServiceContext) => Promise<TService> | TService;
6682
+ dispose?: (instance: TService, ctx: ClientServiceContext) => void | Promise<void>;
6683
+ }): ClientServiceDefinition<TService>;
6684
+
6685
+ export function defineClientService<TService>(definition: {
6686
+ name?: string;
6687
+ setup: (ctx: ClientServiceContext) => Promise<TService> | TService;
6688
+ dispose?: (instance: TService, ctx: ClientServiceContext) => void | Promise<void>;
6689
+ }): ClientServiceDefinition<TService>;
6690
+
6691
+ export function defineClientService<TService>(
6692
+ factory: (ctx: ClientServiceContext) => Promise<TService> | TService
6693
+ ): ClientServiceDefinition<Awaited<TService>>;
6694
+
6695
+ export function createClientServiceRegistry<TServices extends Record<string, any> = AppClientServices>(options?: {
6696
+ root?: Document | HTMLElement | null;
6697
+ api?: ClientApiClient;
6698
+ storage?: ClientStorage;
6699
+ debug?: Record<string, any>;
6700
+ services?: TServices;
6701
+ }): ClientServicesRegistry<TServices>;
6702
+
6703
+ export function createClientHostManager(options?: {
6704
+ root?: Document | HTMLElement | null;
6705
+ debug?: Record<string, any>;
6706
+ }): ClientServiceHostHelper & { dispose(): void; readonly isDisposed: boolean };
6707
+
6536
6708
  export interface ClientFormSubmitResult<TData = any> {
6537
6709
  ok: boolean;
6710
+ submitted?: boolean;
6538
6711
  data?: TData;
6539
6712
  refreshOk?: boolean;
6540
6713
  refreshError?: Error | null;
6714
+ hookError?: Error | null;
6541
6715
  error?: ClientRequestError | Error;
6542
6716
  aborted?: boolean;
6543
6717
  }
6544
6718
 
6719
+ export interface ClientFormHookMeta<
6720
+ TValues extends Record<string, any> = Record<string, any>,
6721
+ TResponse = any,
6722
+ TServices = AppClientServices
6723
+ > {
6724
+ values: TValues;
6725
+ form: ClientFormHandle<TValues, TResponse, TServices>;
6726
+ services: ClientServicesRegistry<TServices>;
6727
+ refreshOk?: boolean;
6728
+ refreshError?: Error | null;
6729
+ }
6730
+
6545
6731
  export interface ClientFormHandle<
6546
6732
  TValues extends Record<string, any> = Record<string, any>,
6547
- TResponse = any
6733
+ TResponse = any,
6734
+ TServices = AppClientServices
6548
6735
  > {
6549
6736
  readonly name: string;
6550
6737
  readonly el: HTMLFormElement | null;
6738
+ readonly services: ClientServicesRegistry<TServices>;
6551
6739
  readonly pending: boolean;
6552
6740
  readonly dirty: boolean;
6741
+ readonly inputRevision: number;
6742
+ readonly draftKey: string;
6743
+ readonly baseline: TValues;
6553
6744
  readonly errors: Record<string, string>;
6554
- readonly formError: string;
6745
+ readonly formError: string | null;
6746
+ readonly lastError: ClientRequestError | Error | null;
6555
6747
  readonly fieldErrors: Partial<Record<keyof TValues & string, string>> & Record<string, string>;
6556
6748
  disabled: boolean;
6557
6749
  values(): TValues;
@@ -6567,23 +6759,44 @@ export interface ClientFormHandle<
6567
6759
  saveDraft(): boolean;
6568
6760
  restoreDraft(): boolean;
6569
6761
  clearDraft(): boolean;
6762
+ setDraftKey(nextKey: string, options?: { restore?: boolean }): this;
6570
6763
  readonly hasDraft: boolean;
6571
- submit(submitter?: HTMLElement | null): Promise<ClientFormSubmitResult<TResponse>>;
6572
- onSuccess(callback: (data: TResponse, meta: { refreshOk: boolean; refreshError: Error | null }) => void): () => void;
6764
+ submit(submitter?: HTMLElement | null | Record<string, unknown>): Promise<ClientFormSubmitResult<TResponse>>;
6765
+ beforeSubmit(
6766
+ callback: (values: TValues, meta: { form: ClientFormHandle<TValues, TResponse, TServices>; submitter?: HTMLElement | null; action: string; method: string }) => boolean | Promise<boolean>
6767
+ ): () => void;
6768
+ onSuccess(
6769
+ callback: (data: TResponse, meta: ClientFormHookMeta<TValues, TResponse, TServices>) => void | Promise<void>
6770
+ ): () => void;
6771
+ onError(
6772
+ callback: (
6773
+ error: ClientRequestError | Error,
6774
+ meta: ClientFormHookMeta<TValues, TResponse, TServices>
6775
+ ) => void | Promise<void>
6776
+ ): () => void;
6573
6777
  destroy(): void;
6574
6778
  }
6575
6779
 
6576
- export interface ControllerFormsRegistry {
6780
+ export interface ControllerFormsRegistry<TServices = AppClientServices> {
6781
+ <TValues extends Record<string, any> = Record<string, any>, TResponse = any>(
6782
+ formNameOrElement: string | HTMLFormElement,
6783
+ options?: {
6784
+ resetOnSuccess?: boolean;
6785
+ clearOnSuccess?: boolean;
6786
+ redirectOnSuccess?: string | ((data: TResponse) => string | void);
6787
+ onSuccess?: (data: TResponse, meta: ClientFormHookMeta<TValues, TResponse, TServices>) => void | Promise<void>;
6788
+ }
6789
+ ): ClientFormHandle<TValues, TResponse, TServices>;
6577
6790
  get<TValues extends Record<string, any> = Record<string, any>, TResponse = any>(
6578
6791
  formNameOrElement: string | HTMLFormElement,
6579
6792
  options?: {
6580
6793
  resetOnSuccess?: boolean;
6581
6794
  clearOnSuccess?: boolean;
6582
6795
  redirectOnSuccess?: string | ((data: TResponse) => string | void);
6583
- onSuccess?: (data: TResponse, meta: { refreshOk: boolean; refreshError: Error | null }) => void;
6796
+ onSuccess?: (data: TResponse, meta: ClientFormHookMeta<TValues, TResponse, TServices>) => void | Promise<void>;
6584
6797
  }
6585
- ): ClientFormHandle<TValues, TResponse>;
6586
- all(): ClientFormHandle[];
6798
+ ): ClientFormHandle<TValues, TResponse, TServices>;
6799
+ all(): ClientFormHandle<any, any, TServices>[];
6587
6800
  }
6588
6801
 
6589
6802
  export interface FragmentRefreshResult {
@@ -6653,31 +6866,38 @@ export interface WatchDescriptor<T = any> extends WatchOptions {
6653
6866
 
6654
6867
  export type ControllerErrorHandler<
6655
6868
  TState extends Record<string, any> = Record<string, any>,
6656
- TTasks extends Record<string, ClientTask> = Record<string, ClientTask>
6869
+ TTasks extends Record<string, ClientTask> = Record<string, ClientTask>,
6870
+ TServices = AppClientServices
6657
6871
  > = (
6658
6872
  err: Error | ClientRequestError,
6659
- ctx: ControllerContext<TState, TTasks>,
6873
+ ctx: ControllerContext<TState, TTasks, TServices>,
6660
6874
  meta?: ControllerErrorMeta
6661
6875
  ) => void | boolean;
6662
6876
 
6663
6877
  export interface ControllerContext<
6664
6878
  TState extends Record<string, any> = Record<string, any>,
6665
- TTasks extends Record<string, ClientTask> = Record<string, ClientTask>
6879
+ TTasks extends Record<string, ClientTask> = Record<string, ClientTask>,
6880
+ TServices = AppClientServices
6666
6881
  > {
6667
6882
  readonly el: HTMLElement;
6668
6883
  readonly instanceId: string;
6669
6884
  readonly name: string;
6670
6885
  readonly state: TState;
6671
6886
  readonly api: ClientApiClient;
6672
- readonly forms: ControllerFormsRegistry;
6887
+ readonly services: ClientServicesRegistry<TServices>;
6888
+ readonly forms: ControllerFormsRegistry<TServices>;
6673
6889
  readonly tasks: TTasks;
6674
6890
  readonly signal: AbortSignal;
6675
6891
  readonly isConnected: () => boolean;
6676
6892
  readonly isDisposed: () => boolean;
6893
+ readonly isBusy: boolean;
6894
+ isActionBusy(actionName: string): boolean;
6677
6895
  readonly lastError: Error | null;
6678
6896
  clearError(): void;
6679
6897
  readonly storage: ClientStorage & { readonly global: ClientStorage; readonly root: ClientStorage };
6898
+ readonly persistenceConflicts: Array<Record<string, unknown>>;
6680
6899
  clearPersistedState(): void;
6900
+ retryFailedFragments(): Promise<FragmentRefreshResult>;
6681
6901
  onError(listener: (err: Error, meta?: ControllerErrorMeta) => void): () => void;
6682
6902
  task<TData = any, TArgs extends unknown[] = any[]>(
6683
6903
  runFn: (...args: TArgs) => Promise<TData>,
@@ -6719,10 +6939,13 @@ export type ControllerComputedGetter<
6719
6939
 
6720
6940
  export type ControllerTaskFactory<
6721
6941
  TState extends Record<string, any> = Record<string, any>,
6722
- TData = any
6942
+ TData = any,
6943
+ TServices = AppClientServices
6723
6944
  > =
6724
- | ((ctx: ControllerContext<TState>) => ClientTask<TData> | { run: (...args: any[]) => Promise<TData>; concurrency?: ClientConcurrencyPolicy; key?: string })
6725
- | { run: (...args: any[]) => Promise<TData>; concurrency?: ClientConcurrencyPolicy; key?: string };
6945
+ | ((
6946
+ ctx: ControllerContext<TState, Record<string, ClientTask>, TServices>
6947
+ ) => ClientTask<TData> | ({ run: (...args: any[]) => Promise<TData> } & ClientTaskOptions))
6948
+ | ({ run: (...args: any[]) => Promise<TData> } & ClientTaskOptions);
6726
6949
 
6727
6950
  export interface ControllerElement extends HTMLElement {
6728
6951
  data(): Record<string, unknown>;
@@ -6733,9 +6956,10 @@ export interface ControllerElement extends HTMLElement {
6733
6956
 
6734
6957
  export type ControllerActionHandler<
6735
6958
  TState extends Record<string, any> = Record<string, any>,
6736
- TTasks extends Record<string, ClientTask> = Record<string, ClientTask>
6959
+ TTasks extends Record<string, ClientTask> = Record<string, ClientTask>,
6960
+ TServices = AppClientServices
6737
6961
  > = (
6738
- ctx: ControllerContext<TState, TTasks>,
6962
+ ctx: ControllerContext<TState, TTasks, TServices>,
6739
6963
  event: Event,
6740
6964
  actionEl: ControllerElement
6741
6965
  ) => unknown | Promise<unknown>;
@@ -6743,7 +6967,8 @@ export type ControllerActionHandler<
6743
6967
  export interface ControllerDefinition<
6744
6968
  TState extends Record<string, any> = Record<string, any>,
6745
6969
  TComputed extends Record<string, ControllerComputedGetter<TState>> = Record<string, ControllerComputedGetter<TState>>,
6746
- TTasks extends Record<string, ControllerTaskFactory<TState>> = Record<string, ControllerTaskFactory<TState>>
6970
+ TTasks extends Record<string, ControllerTaskFactory<TState, any, TServices>> = Record<string, ControllerTaskFactory<TState, any, any>>,
6971
+ TServices = AppClientServices
6747
6972
  > {
6748
6973
  name?: string;
6749
6974
  state?: () => TState;
@@ -6751,22 +6976,30 @@ export interface ControllerDefinition<
6751
6976
  tasks?: TTasks;
6752
6977
  connect?: (
6753
6978
  ctx: ControllerContext<
6754
- [TState][TState extends any ? 0 : never] & { readonly [K in keyof TComputed]: ReturnType<TComputed[K]> }
6979
+ [TState][TState extends any ? 0 : never] & { readonly [K in keyof TComputed]: ReturnType<TComputed[K]> },
6980
+ Record<string, ClientTask>,
6981
+ TServices
6755
6982
  >
6756
6983
  ) => void | (() => void);
6757
6984
  disconnect?: (
6758
6985
  ctx: ControllerContext<
6759
- [TState][TState extends any ? 0 : never] & { readonly [K in keyof TComputed]: ReturnType<TComputed[K]> }
6986
+ [TState][TState extends any ? 0 : never] & { readonly [K in keyof TComputed]: ReturnType<TComputed[K]> },
6987
+ Record<string, ClientTask>,
6988
+ TServices
6760
6989
  >
6761
6990
  ) => void;
6762
6991
  onError?: ControllerErrorHandler<
6763
- [TState][TState extends any ? 0 : never] & { readonly [K in keyof TComputed]: ReturnType<TComputed[K]> }
6992
+ [TState][TState extends any ? 0 : never] & { readonly [K in keyof TComputed]: ReturnType<TComputed[K]> },
6993
+ Record<string, ClientTask>,
6994
+ TServices
6764
6995
  >;
6765
6996
  persist?: ControllerPersistConfig<TState> | (keyof TState & string)[] | 'local' | 'session' | null;
6766
6997
  watch?: Record<string, WatchCallback<any> | WatchDescriptor<any>>;
6767
6998
  actions?: {
6768
6999
  [actionName: string]: ControllerActionHandler<
6769
- [TState][TState extends any ? 0 : never] & { readonly [K in keyof TComputed]: ReturnType<TComputed[K]> }
7000
+ [TState][TState extends any ? 0 : never] & { readonly [K in keyof TComputed]: ReturnType<TComputed[K]> },
7001
+ Record<string, ClientTask>,
7002
+ TServices
6770
7003
  >;
6771
7004
  };
6772
7005
  }
@@ -6774,10 +7007,11 @@ export interface ControllerDefinition<
6774
7007
  export function defineController<
6775
7008
  TState extends Record<string, any> = Record<string, any>,
6776
7009
  TComputed extends Record<string, ControllerComputedGetter<TState>> = Record<string, ControllerComputedGetter<TState>>,
6777
- TTasks extends Record<string, ControllerTaskFactory<TState>> = Record<string, ControllerTaskFactory<TState>>
7010
+ TTasks extends Record<string, ControllerTaskFactory<TState, any, TServices>> = Record<string, ControllerTaskFactory<TState, any, any>>,
7011
+ TServices = AppClientServices
6778
7012
  >(
6779
- definition: ControllerDefinition<TState, TComputed, TTasks>
6780
- ): ControllerDefinition<TState, TComputed, TTasks> & { __isWebspressoController: true };
7013
+ definition: ControllerDefinition<TState, TComputed, TTasks, TServices>
7014
+ ): ControllerDefinition<TState, TComputed, TTasks, TServices> & { __isWebspressoController: true };
6781
7015
 
6782
7016
  export function watch<T = any>(
6783
7017
  source: WatchSource<T>,
@@ -6810,6 +7044,14 @@ export interface FragmentDefinition<TInput = Record<string, unknown>, TData = Re
6810
7044
  schema?: ZodTypeAny | Record<string, ZodTypeAny> | ((helpers: { z: typeof z }) => ZodTypeAny | Record<string, ZodTypeAny>);
6811
7045
  auth?: boolean | string | string[] | ((user: any, ctx: PageContext) => boolean | Promise<boolean>);
6812
7046
  middleware?: Array<string | import('express').RequestHandler>;
7047
+ staleTime?: number | string;
7048
+ refetchOnWindowFocus?: ClientRefetchPolicy;
7049
+ refetchOnFocus?: ClientRefetchPolicy;
7050
+ refetchOnReconnect?: ClientRefetchPolicy;
7051
+ refetchOnMount?: ClientRefetchPolicy;
7052
+ refetchOnVisit?: ClientRefetchPolicy;
7053
+ refetchInterval?: number | string | false;
7054
+ refetchIntervalInBackground?: boolean;
6813
7055
  load?: (context: FragmentLoaderContext<TInput>) => TData | Promise<TData>;
6814
7056
  }
6815
7057
 
@@ -6846,11 +7088,74 @@ export function parseFormElement(formEl: HTMLFormElement, options?: Record<strin
6846
7088
  hasFile: boolean;
6847
7089
  formData: FormData;
6848
7090
  };
7091
+ export interface ClientRuntimeOptions<TServices extends Record<string, any> = AppClientServices> {
7092
+ root?: Document | Element;
7093
+ document?: Document | Element;
7094
+ fetch?: typeof fetch;
7095
+ baseUrl?: string;
7096
+ fragmentEndpoint?: string;
7097
+ datastar?: Record<string, unknown>;
7098
+ debug?: boolean | Record<string, unknown>;
7099
+ devtools?: boolean;
7100
+ devtoolsOptions?: Record<string, unknown>;
7101
+ observe?: boolean;
7102
+ hmr?: boolean;
7103
+ staleTime?: number | string;
7104
+ refetchOnWindowFocus?: ClientRefetchPolicy;
7105
+ refetchOnFocus?: ClientRefetchPolicy;
7106
+ refetchOnReconnect?: ClientRefetchPolicy;
7107
+ refetchOnMount?: ClientRefetchPolicy;
7108
+ refetchOnVisit?: ClientRefetchPolicy;
7109
+ refetchInterval?: number | string | false;
7110
+ refetchIntervalInBackground?: boolean;
7111
+ lazyLoader?: (name: string, el: Element) => Promise<any>;
7112
+ controllers?: Record<string, any>;
7113
+ services?: TServices;
7114
+ [key: string]: unknown;
7115
+ }
7116
+
7117
+ export interface ClientRuntime<TServices = AppClientServices> {
7118
+ readonly api: ClientApiClient;
7119
+ readonly services: ClientServicesRegistry<TServices>;
7120
+ readonly fragments: Record<string, any>;
7121
+ readonly controllers: Record<string, any>;
7122
+ readonly datastar: Record<string, any>;
7123
+ readonly adapter: Record<string, any>;
7124
+ readonly debug: Record<string, any>;
7125
+ register(name: string, definition: any, meta?: Record<string, unknown>): any;
7126
+ registerService<TDef>(name: string, definition: TDef): ClientServiceDefinition<InferClientService<TDef>>;
7127
+ mount(targetRoot?: Document | Element): Promise<any[]>;
7128
+ unmount(targetRoot?: Document | Element): void;
7129
+ destroy(): void;
7130
+ dispose(): void;
7131
+ getControllerInstance(el: Element, name?: string): any;
7132
+ getController(el: Element, name?: string): any;
7133
+ invalidate(tags: string | string[], meta?: Record<string, unknown>): Promise<any>;
7134
+ refresh(idOrName: string, input?: Record<string, unknown>, opts?: FragmentRefreshOptions): Promise<FragmentRefreshResult>;
7135
+ mountDevtool(opts?: Record<string, unknown>): ClientDevtoolHandle;
7136
+ forms: {
7137
+ parse: typeof parseFormElement;
7138
+ create<TValues extends Record<string, any> = Record<string, any>, TResponse = any>(
7139
+ formEl: HTMLFormElement,
7140
+ formOpts?: Record<string, unknown>
7141
+ ): ClientFormHandle<TValues, TResponse, TServices>;
7142
+ };
7143
+ [key: string]: any;
7144
+ }
7145
+
6849
7146
  export function createFragmentCoordinator(options?: Record<string, unknown>): Record<string, any>;
6850
- export function createClientRuntime(options?: Record<string, unknown>): Record<string, any>;
6851
- export function bootClient(options?: Record<string, unknown>): Record<string, any>;
6852
- export function createLiteClientRuntime(options?: Record<string, unknown>): Record<string, any>;
6853
- export function bootLiteClient(options?: Record<string, unknown>): Record<string, any>;
7147
+ export function createClientRuntime<TServices extends Record<string, any> = AppClientServices>(
7148
+ options?: ClientRuntimeOptions<TServices>
7149
+ ): ClientRuntime<TServices>;
7150
+ export function bootClient<TServices extends Record<string, any> = AppClientServices>(
7151
+ options?: ClientRuntimeOptions<TServices>
7152
+ ): ClientRuntime<TServices>;
7153
+ export function createLiteClientRuntime<TServices extends Record<string, any> = AppClientServices>(
7154
+ options?: ClientRuntimeOptions<TServices>
7155
+ ): Record<string, any> & { readonly services: ClientServicesRegistry<TServices> };
7156
+ export function bootLiteClient<TServices extends Record<string, any> = AppClientServices>(
7157
+ options?: ClientRuntimeOptions<TServices>
7158
+ ): Record<string, any> & { readonly services: ClientServicesRegistry<TServices> };
6854
7159
  export function createDatastarAdapter(options?: Record<string, unknown>): Record<string, any>;
6855
7160
  export function createClientDebugger(options?: { enabled?: boolean; maxEvents?: number }): Record<string, any>;
6856
7161
  export interface ClientDevtoolHandle {
package/index.js CHANGED
@@ -799,6 +799,9 @@ Object.defineProperties(module.exports, {
799
799
  // Datastar Client Behavior Layer & SSR Fragments (core/client)
800
800
  client: { get: () => require('./core/client'), enumerable: true, configurable: true },
801
801
  defineController: { get: () => require('./core/client').defineController, enumerable: true, configurable: true },
802
+ defineClientService: { get: () => require('./core/client').defineClientService, enumerable: true, configurable: true },
803
+ createClientServiceRegistry: { get: () => require('./core/client').createClientServiceRegistry, enumerable: true, configurable: true },
804
+ createClientHostManager: { get: () => require('./core/client').createClientHostManager, enumerable: true, configurable: true },
802
805
  deriveControllerNameFromPath: { get: () => require('./core/client').deriveControllerNameFromPath, enumerable: true, configurable: true },
803
806
  createClientRuntime: { get: () => require('./core/client').createClientRuntime, enumerable: true, configurable: true },
804
807
  bootClient: { get: () => require('./core/client').bootClient, enumerable: true, configurable: true },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "webspresso",
3
- "version": "0.0.110",
3
+ "version": "0.0.112",
4
4
  "description": "Minimal, production-ready SSR framework for Node.js with file-based routing, Nunjucks templating, built-in i18n, and CLI tooling",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",