@electrojs/runtime 1.0.8 → 1.0.9
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/index.d.mts +498 -496
- package/package.json +5 -5
package/dist/index.d.mts
CHANGED
|
@@ -473,64 +473,318 @@ declare class AppKernel {
|
|
|
473
473
|
private safeDisposeServices;
|
|
474
474
|
}
|
|
475
475
|
//#endregion
|
|
476
|
-
//#region src/
|
|
476
|
+
//#region src/desktop/view-manager.d.ts
|
|
477
477
|
/**
|
|
478
|
-
*
|
|
478
|
+
* Framework-internal registry that tracks all `@View()` providers in the application.
|
|
479
479
|
*
|
|
480
|
-
*
|
|
481
|
-
*
|
|
482
|
-
* {@link
|
|
480
|
+
* Handles registration (including injecting the source URL into the base class)
|
|
481
|
+
* and provides lookup by view ID. Consumers typically interact with views through
|
|
482
|
+
* their {@link ViewProvider} subclass rather than this manager directly.
|
|
483
483
|
*
|
|
484
|
-
* @
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
484
|
+
* @internal
|
|
485
|
+
*/
|
|
486
|
+
declare class ViewManager {
|
|
487
|
+
private readonly views;
|
|
488
|
+
/**
|
|
489
|
+
* Register a view provider and apply its `@View()` source URL.
|
|
490
|
+
*
|
|
491
|
+
* @remarks Silently skips providers that do not have view metadata.
|
|
492
|
+
*/
|
|
493
|
+
register(providerRef: ProviderRef): void;
|
|
494
|
+
/** Look up a registered view provider by its view ID. */
|
|
495
|
+
get(viewId: string): ProviderRef | undefined;
|
|
496
|
+
/** Return all registered view providers. */
|
|
497
|
+
list(): readonly ProviderRef[];
|
|
498
|
+
/** Clear the registry. Does not destroy any underlying web contents. */
|
|
499
|
+
dispose(): Promise<void>;
|
|
500
|
+
}
|
|
501
|
+
//#endregion
|
|
502
|
+
//#region src/desktop/view-provider.d.ts
|
|
503
|
+
declare const VIEW_STATE: unique symbol;
|
|
504
|
+
interface ViewAuthoringSurface {
|
|
505
|
+
readonly contentView: WebContentsView | undefined;
|
|
506
|
+
readonly webContents: WebContents | undefined;
|
|
507
|
+
load(): Promise<void>;
|
|
508
|
+
setBounds(bounds: Rectangle): void;
|
|
509
|
+
setBackgroundColor(color: string): void;
|
|
510
|
+
focus(): void;
|
|
511
|
+
setWindowButtonVisibility(visible: boolean): void;
|
|
512
|
+
}
|
|
513
|
+
/**
|
|
514
|
+
* Abstract base class for view providers decorated with `@View()`.
|
|
489
515
|
*
|
|
490
|
-
*
|
|
491
|
-
*
|
|
516
|
+
* Extend this class to define a renderable view in your application. The framework
|
|
517
|
+
* injects the source URL from the `@View()` decorator, and your subclass gains access
|
|
518
|
+
* to methods for loading content, positioning, and styling.
|
|
519
|
+
*
|
|
520
|
+
* Views are created with strict security defaults: `sandbox: true`,
|
|
521
|
+
* `contextIsolation: true`, and `nodeIntegration: false`.
|
|
522
|
+
*
|
|
523
|
+
* @remarks The `WebContentsView` is lazily created on the first call to {@link load}.
|
|
492
524
|
*
|
|
493
525
|
* @example
|
|
494
526
|
* ```ts
|
|
495
|
-
* @
|
|
496
|
-
* class
|
|
497
|
-
*
|
|
527
|
+
* @View({ source: 'view:main', access: ['app:getVersion'] })
|
|
528
|
+
* class MainView extends ViewProvider {
|
|
529
|
+
* async onStart() {
|
|
530
|
+
* await this.load();
|
|
531
|
+
* this.setBounds({ x: 0, y: 0, width: 800, height: 600 });
|
|
532
|
+
* }
|
|
498
533
|
* }
|
|
499
534
|
* ```
|
|
535
|
+
*/
|
|
536
|
+
declare abstract class ViewProvider {
|
|
537
|
+
private [VIEW_STATE];
|
|
538
|
+
/** The underlying Electron `WebContentsView`, or `undefined` if not yet created. */
|
|
539
|
+
get contentView(): WebContentsView | undefined;
|
|
540
|
+
/** The `WebContents` associated with this view, or `undefined` if not yet created. */
|
|
541
|
+
get webContents(): WebContents | undefined;
|
|
542
|
+
/**
|
|
543
|
+
* Create the underlying `WebContentsView` (if needed) and load the configured source URL.
|
|
544
|
+
*
|
|
545
|
+
* The view is lazily created on the first call. Subsequent calls reload the source.
|
|
546
|
+
* If the previous view was destroyed (e.g. parent window closed), a new one is created.
|
|
547
|
+
* No-ops if no source URL has been configured.
|
|
548
|
+
*/
|
|
549
|
+
load(): Promise<void>;
|
|
550
|
+
/** Set the position and size of this view within its parent window. */
|
|
551
|
+
setBounds(bounds: Rectangle): void;
|
|
552
|
+
/** Set the background color of the view (e.g. `"#ffffff"` or `"transparent"`). */
|
|
553
|
+
setBackgroundColor(color: string): void;
|
|
554
|
+
/** Give keyboard focus to this view's web contents. */
|
|
555
|
+
focus(): void;
|
|
556
|
+
/** Show or hide the native window traffic-light buttons for this view (macOS). */
|
|
557
|
+
setWindowButtonVisibility(visible: boolean): void;
|
|
558
|
+
private createView;
|
|
559
|
+
private static resolveSource;
|
|
560
|
+
/** @internal Called by the framework to set the view source from @View metadata. */
|
|
561
|
+
static __setSource(instance: ViewProvider, source: string): void;
|
|
562
|
+
/** @internal Called by the framework to set web preferences from @View metadata. */
|
|
563
|
+
static __setWebPreferences(instance: ViewProvider, webPreferences: WebPreferences): void;
|
|
564
|
+
}
|
|
565
|
+
//#endregion
|
|
566
|
+
//#region src/desktop/window-manager.d.ts
|
|
567
|
+
/**
|
|
568
|
+
* Framework-internal registry that tracks all `@Window()` providers in the application.
|
|
500
569
|
*
|
|
501
|
-
*
|
|
570
|
+
* Handles registration (including injecting `@Window()` configuration into the base class)
|
|
571
|
+
* and provides lookup by window ID. Consumers typically interact with windows through
|
|
572
|
+
* their {@link WindowProvider} subclass rather than this manager directly.
|
|
573
|
+
*
|
|
574
|
+
* @internal
|
|
502
575
|
*/
|
|
503
|
-
declare
|
|
576
|
+
declare class WindowManager {
|
|
577
|
+
private readonly windows;
|
|
578
|
+
/**
|
|
579
|
+
* Register a window provider and apply its `@Window()` configuration.
|
|
580
|
+
*
|
|
581
|
+
* @remarks Silently skips providers that do not have window metadata.
|
|
582
|
+
*/
|
|
583
|
+
register(providerRef: ProviderRef): void;
|
|
584
|
+
/** Look up a registered window provider by its window ID. */
|
|
585
|
+
get(windowId: string): ProviderRef | undefined;
|
|
586
|
+
/** Return all registered window providers. */
|
|
587
|
+
list(): readonly ProviderRef[];
|
|
588
|
+
/** Close all managed windows and clear the registry. */
|
|
589
|
+
dispose(): Promise<void>;
|
|
590
|
+
}
|
|
504
591
|
//#endregion
|
|
505
|
-
//#region src/
|
|
592
|
+
//#region src/desktop/window-provider.d.ts
|
|
593
|
+
declare const WINDOW_STATE: unique symbol;
|
|
594
|
+
interface WindowAuthoringSurface {
|
|
595
|
+
readonly window: BaseWindow | undefined;
|
|
596
|
+
create(): void;
|
|
597
|
+
mount(view: Pick<ViewProvider, "contentView">): void;
|
|
598
|
+
show(): void;
|
|
599
|
+
hide(): void;
|
|
600
|
+
focus(): void;
|
|
601
|
+
close(): void;
|
|
602
|
+
getBounds(): Rectangle | undefined;
|
|
603
|
+
}
|
|
506
604
|
/**
|
|
507
|
-
*
|
|
605
|
+
* Abstract base class for window providers decorated with `@Window()`.
|
|
508
606
|
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
607
|
+
* Extend this class to define a window in your application. The framework injects
|
|
608
|
+
* configuration from the `@Window()` decorator metadata, and your subclass gains
|
|
609
|
+
* access to lifecycle methods like {@link create}, {@link show}, {@link mount}, and {@link close}.
|
|
512
610
|
*
|
|
513
|
-
* @remarks
|
|
514
|
-
*
|
|
515
|
-
*
|
|
611
|
+
* @remarks The native `BaseWindow` instance is only available after calling {@link create}.
|
|
612
|
+
* Calling lifecycle methods before `create()` is safe (they no-op) but the window
|
|
613
|
+
* will not exist on screen.
|
|
516
614
|
*
|
|
517
|
-
* @
|
|
615
|
+
* @example
|
|
616
|
+
* ```ts
|
|
617
|
+
* @Window({ width: 800, height: 600, show: false })
|
|
618
|
+
* class MainWindow extends WindowProvider {
|
|
619
|
+
* async onStart() {
|
|
620
|
+
* this.create();
|
|
621
|
+
* this.mount(this.mainView);
|
|
622
|
+
* this.show();
|
|
623
|
+
* }
|
|
624
|
+
* }
|
|
625
|
+
* ```
|
|
518
626
|
*/
|
|
519
|
-
declare
|
|
627
|
+
declare abstract class WindowProvider {
|
|
628
|
+
private [WINDOW_STATE];
|
|
629
|
+
/** The underlying Electron `BaseWindow` instance, or `undefined` if not yet created. */
|
|
630
|
+
get window(): BaseWindow | undefined;
|
|
631
|
+
/** Create the native `BaseWindow` using configuration from the `@Window()` decorator. */
|
|
632
|
+
create(): void;
|
|
520
633
|
/**
|
|
521
|
-
*
|
|
522
|
-
*
|
|
634
|
+
* Attach a view's content to this window.
|
|
635
|
+
*
|
|
636
|
+
* The view's `WebContentsView` is added as a child view of the window's content area.
|
|
637
|
+
* No-ops silently if the window or view has not been created yet.
|
|
523
638
|
*/
|
|
524
|
-
|
|
639
|
+
mount(view: ViewProvider): void;
|
|
640
|
+
/** Show the window. No-ops if the window has not been created. */
|
|
641
|
+
show(): void;
|
|
642
|
+
/** Hide the window without destroying it. */
|
|
643
|
+
hide(): void;
|
|
644
|
+
/** Bring the window to the front and give it focus. */
|
|
645
|
+
focus(): void;
|
|
646
|
+
/** Close and destroy the native window, releasing its resources. */
|
|
647
|
+
close(): void;
|
|
648
|
+
/** Return the window's current screen bounds, or `undefined` if not created. */
|
|
649
|
+
getBounds(): Rectangle | undefined;
|
|
650
|
+
/** @internal Called by the framework to set the window configuration from @Window metadata. */
|
|
651
|
+
static __setConfiguration(instance: WindowProvider, configuration?: BaseWindowConstructorOptions): void;
|
|
652
|
+
}
|
|
653
|
+
//#endregion
|
|
654
|
+
//#region src/jobs/context.d.ts
|
|
655
|
+
/**
|
|
656
|
+
* Execution context passed to every job handler invocation.
|
|
657
|
+
*
|
|
658
|
+
* Provides cooperative cancellation and progress reporting. The handler should
|
|
659
|
+
* periodically check {@link isCanceled} and abort work when it returns `true`.
|
|
660
|
+
*
|
|
661
|
+
* @example
|
|
662
|
+
* ```ts
|
|
663
|
+
* async function cleanupHandler(ctx: JobContext) {
|
|
664
|
+
* const items = await fetchItems();
|
|
665
|
+
* for (let i = 0; i < items.length; i++) {
|
|
666
|
+
* if (ctx.isCanceled) return;
|
|
667
|
+
* await processItem(items[i]);
|
|
668
|
+
* ctx.setProgress((i / items.length) * 100);
|
|
669
|
+
* }
|
|
670
|
+
* }
|
|
671
|
+
* ```
|
|
672
|
+
*/
|
|
673
|
+
declare class JobContext {
|
|
674
|
+
private canceledInternal;
|
|
675
|
+
private progressInternal;
|
|
676
|
+
/** Whether cancellation has been requested for this execution. */
|
|
677
|
+
get isCanceled(): boolean;
|
|
678
|
+
/** Current progress value, clamped to 0-100. */
|
|
679
|
+
get progress(): number;
|
|
525
680
|
/**
|
|
526
|
-
*
|
|
527
|
-
*
|
|
681
|
+
* Report execution progress.
|
|
682
|
+
*
|
|
683
|
+
* @remarks Values are clamped to the 0-100 range.
|
|
528
684
|
*/
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
685
|
+
setProgress(value: number): void;
|
|
686
|
+
/** @internal */
|
|
687
|
+
cancel(): void;
|
|
688
|
+
}
|
|
689
|
+
//#endregion
|
|
690
|
+
//#region src/jobs/registry.d.ts
|
|
691
|
+
type Awaitable$1<T> = T | PromiseLike<T>;
|
|
692
|
+
/**
|
|
693
|
+
* Describes a job as provided during module bootstrap.
|
|
694
|
+
*
|
|
695
|
+
* @internal Consumed by {@link JobRegistry.register}; not intended for direct consumer use.
|
|
696
|
+
*/
|
|
697
|
+
interface JobDefinitionRecord {
|
|
698
|
+
readonly jobId: string;
|
|
699
|
+
/** Cron expression (Croner syntax). Omit for manually-triggered-only jobs. */
|
|
700
|
+
readonly cron?: string;
|
|
701
|
+
/** The handler to execute. Receives a {@link JobContext} for cancellation/progress, plus any extra args from manual runs. */
|
|
702
|
+
readonly handler: (context: JobContext, ...args: unknown[]) => Awaitable$1<unknown>;
|
|
703
|
+
/** Injector used to restore the DI context when the handler runs. */
|
|
704
|
+
readonly injector: Injector;
|
|
705
|
+
}
|
|
706
|
+
/** Lifecycle state of a registered job. */
|
|
707
|
+
type JobStatus = "idle" | "scheduled" | "running";
|
|
708
|
+
/** Read-only snapshot of a job's current runtime state. */
|
|
709
|
+
interface JobRuntimeState {
|
|
710
|
+
readonly jobId: string;
|
|
711
|
+
readonly status: JobStatus;
|
|
712
|
+
/** Last reported progress value (0-100). */
|
|
713
|
+
readonly progress: number;
|
|
714
|
+
/** Epoch timestamp of the last completed execution, if any. */
|
|
715
|
+
readonly lastRunAt?: number;
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Manages the lifecycle of scheduled and manually-triggered jobs.
|
|
719
|
+
*
|
|
720
|
+
* Jobs are registered during bootstrap (via `@internal` {@link register}), then consumers
|
|
721
|
+
* interact through `start`, `stop`, `run`, and `cancel`. Scheduled jobs use Croner for
|
|
722
|
+
* cron-based timing; each execution receives a fresh {@link JobContext} for progress
|
|
723
|
+
* reporting and cooperative cancellation.
|
|
724
|
+
*
|
|
725
|
+
* @example
|
|
726
|
+
* ```ts
|
|
727
|
+
* // Start the cron scheduler for a registered job
|
|
728
|
+
* jobRegistry.start('data:cleanup');
|
|
729
|
+
*
|
|
730
|
+
* // Trigger an immediate (manual) execution
|
|
731
|
+
* await jobRegistry.run('data:cleanup');
|
|
732
|
+
*
|
|
733
|
+
* // Cancel a running execution cooperatively
|
|
734
|
+
* jobRegistry.cancel('data:cleanup');
|
|
735
|
+
*
|
|
736
|
+
* // Stop the cron scheduler and wait for any running execution to finish
|
|
737
|
+
* await jobRegistry.stop('data:cleanup');
|
|
738
|
+
* ```
|
|
739
|
+
*/
|
|
740
|
+
declare class JobRegistry {
|
|
741
|
+
private readonly jobs;
|
|
742
|
+
/** @internal Register a job definition during bootstrap. */
|
|
743
|
+
register(definition: JobDefinitionRecord): void;
|
|
744
|
+
/** Return a snapshot of all registered jobs and their current state. */
|
|
745
|
+
list(): readonly JobRuntimeState[];
|
|
746
|
+
/** Return the current state of a single job, or `undefined` if not registered. */
|
|
747
|
+
getStatus(jobId: string): JobRuntimeState | undefined;
|
|
748
|
+
/**
|
|
749
|
+
* Start the cron scheduler for a job if it is not already scheduled.
|
|
750
|
+
*
|
|
751
|
+
* Unlike {@link start}, this is idempotent and will not throw if the scheduler
|
|
752
|
+
* is already running.
|
|
753
|
+
*/
|
|
754
|
+
ensure(jobId: string): void;
|
|
755
|
+
/**
|
|
756
|
+
* Start the cron scheduler for a job.
|
|
757
|
+
*
|
|
758
|
+
* @throws {JobError} If the job already has an active scheduler.
|
|
759
|
+
*/
|
|
760
|
+
start(jobId: string): void;
|
|
761
|
+
/**
|
|
762
|
+
* Trigger an immediate (manual) execution of a job, bypassing the cron schedule.
|
|
763
|
+
*
|
|
764
|
+
* @throws {JobError} If the job is already running.
|
|
765
|
+
* @returns The value returned by the job handler.
|
|
766
|
+
*/
|
|
767
|
+
run(jobId: string, ...args: unknown[]): Promise<unknown>;
|
|
768
|
+
/**
|
|
769
|
+
* Stop the cron scheduler and cancel any in-flight execution.
|
|
770
|
+
*
|
|
771
|
+
* Waits for the running execution (if any) to settle before returning. The job
|
|
772
|
+
* transitions to `"idle"` once fully stopped.
|
|
773
|
+
*/
|
|
774
|
+
stop(jobId: string): Promise<void>;
|
|
775
|
+
/**
|
|
776
|
+
* Request cooperative cancellation of the currently running execution.
|
|
777
|
+
*
|
|
778
|
+
* Sets the `isCanceled` flag on the job's {@link JobContext}. The handler is
|
|
779
|
+
* responsible for checking this flag and aborting work accordingly.
|
|
780
|
+
*/
|
|
781
|
+
cancel(jobId: string): void;
|
|
782
|
+
/** @internal */
|
|
783
|
+
dispose(): Promise<void>;
|
|
784
|
+
private getJobOrThrow;
|
|
785
|
+
private startScheduler;
|
|
786
|
+
private executeJob;
|
|
787
|
+
}
|
|
534
788
|
//#endregion
|
|
535
789
|
//#region src/modules/registry.d.ts
|
|
536
790
|
/**
|
|
@@ -591,24 +845,6 @@ declare class ModuleRegistry {
|
|
|
591
845
|
snapshot(): readonly ModuleSnapshot[];
|
|
592
846
|
}
|
|
593
847
|
//#endregion
|
|
594
|
-
//#region src/modules/validator.d.ts
|
|
595
|
-
/**
|
|
596
|
-
* Validates a scanned {@link AppDefinition} for structural correctness before bootstrap.
|
|
597
|
-
*
|
|
598
|
-
* Checks performed:
|
|
599
|
-
* - Unique module IDs
|
|
600
|
-
* - Exports reference declared providers
|
|
601
|
-
* - No cyclic module imports
|
|
602
|
-
* - Unique view/window IDs
|
|
603
|
-
* - Unique bridge channel names
|
|
604
|
-
* - Unique job IDs
|
|
605
|
-
* - Provider role exclusivity (a class cannot be both a view and a window)
|
|
606
|
-
* - View access references point to existing bridge channels
|
|
607
|
-
*
|
|
608
|
-
* @throws {BootstrapError} On the first validation failure encountered.
|
|
609
|
-
*/
|
|
610
|
-
declare function validateAppDefinition(definition: AppDefinition): void;
|
|
611
|
-
//#endregion
|
|
612
848
|
//#region src/signals/relay.d.ts
|
|
613
849
|
/**
|
|
614
850
|
* Callback invoked by {@link PublicationRelay} whenever a signal is published.
|
|
@@ -684,399 +920,264 @@ declare class SignalBus {
|
|
|
684
920
|
private readonly handlers;
|
|
685
921
|
private readonly relay;
|
|
686
922
|
/**
|
|
687
|
-
* Register a handler for the given signal.
|
|
688
|
-
*
|
|
689
|
-
* The handler is bound to the current injection context at call time, so
|
|
690
|
-
* `inject()` resolves correctly even though the handler runs asynchronously.
|
|
691
|
-
*
|
|
692
|
-
* @returns A dispose function that removes the subscription.
|
|
693
|
-
*/
|
|
694
|
-
subscribe<T>(signalId: string, handler: SignalHandler<T>): () => void;
|
|
695
|
-
/**
|
|
696
|
-
* Publish a signal to all registered handlers.
|
|
697
|
-
*
|
|
698
|
-
* Handlers are invoked asynchronously via `queueMicrotask` and their errors are
|
|
699
|
-
* logged but never propagated to the publisher. The signal is also forwarded to
|
|
700
|
-
* any connected {@link PublicationRelay} listeners (e.g. renderer processes).
|
|
701
|
-
*
|
|
702
|
-
* @remarks Payload is optional for signals that carry no data (`SignalBus.publish<void>('app:ready')`).
|
|
703
|
-
*/
|
|
704
|
-
publish<T = void>(signalId: string, payload?: T): void;
|
|
705
|
-
/** @internal Connect a relay listener (used by renderer registry). */
|
|
706
|
-
connectRelay(listener: SignalPublishListener): () => void;
|
|
707
|
-
}
|
|
708
|
-
//#endregion
|
|
709
|
-
//#region src/jobs/context.d.ts
|
|
710
|
-
/**
|
|
711
|
-
* Execution context passed to every job handler invocation.
|
|
712
|
-
*
|
|
713
|
-
* Provides cooperative cancellation and progress reporting. The handler should
|
|
714
|
-
* periodically check {@link isCanceled} and abort work when it returns `true`.
|
|
715
|
-
*
|
|
716
|
-
* @example
|
|
717
|
-
* ```ts
|
|
718
|
-
* async function cleanupHandler(ctx: JobContext) {
|
|
719
|
-
* const items = await fetchItems();
|
|
720
|
-
* for (let i = 0; i < items.length; i++) {
|
|
721
|
-
* if (ctx.isCanceled) return;
|
|
722
|
-
* await processItem(items[i]);
|
|
723
|
-
* ctx.setProgress((i / items.length) * 100);
|
|
724
|
-
* }
|
|
725
|
-
* }
|
|
726
|
-
* ```
|
|
727
|
-
*/
|
|
728
|
-
declare class JobContext {
|
|
729
|
-
private canceledInternal;
|
|
730
|
-
private progressInternal;
|
|
731
|
-
/** Whether cancellation has been requested for this execution. */
|
|
732
|
-
get isCanceled(): boolean;
|
|
733
|
-
/** Current progress value, clamped to 0-100. */
|
|
734
|
-
get progress(): number;
|
|
735
|
-
/**
|
|
736
|
-
* Report execution progress.
|
|
737
|
-
*
|
|
738
|
-
* @remarks Values are clamped to the 0-100 range.
|
|
739
|
-
*/
|
|
740
|
-
setProgress(value: number): void;
|
|
741
|
-
/** @internal */
|
|
742
|
-
cancel(): void;
|
|
743
|
-
}
|
|
744
|
-
//#endregion
|
|
745
|
-
//#region src/jobs/registry.d.ts
|
|
746
|
-
type Awaitable$1<T> = T | PromiseLike<T>;
|
|
747
|
-
/**
|
|
748
|
-
* Describes a job as provided during module bootstrap.
|
|
749
|
-
*
|
|
750
|
-
* @internal Consumed by {@link JobRegistry.register}; not intended for direct consumer use.
|
|
751
|
-
*/
|
|
752
|
-
interface JobDefinitionRecord {
|
|
753
|
-
readonly jobId: string;
|
|
754
|
-
/** Cron expression (Croner syntax). Omit for manually-triggered-only jobs. */
|
|
755
|
-
readonly cron?: string;
|
|
756
|
-
/** The handler to execute. Receives a {@link JobContext} for cancellation/progress, plus any extra args from manual runs. */
|
|
757
|
-
readonly handler: (context: JobContext, ...args: unknown[]) => Awaitable$1<unknown>;
|
|
758
|
-
/** Injector used to restore the DI context when the handler runs. */
|
|
759
|
-
readonly injector: Injector;
|
|
760
|
-
}
|
|
761
|
-
/** Lifecycle state of a registered job. */
|
|
762
|
-
type JobStatus = "idle" | "scheduled" | "running";
|
|
763
|
-
/** Read-only snapshot of a job's current runtime state. */
|
|
764
|
-
interface JobRuntimeState {
|
|
765
|
-
readonly jobId: string;
|
|
766
|
-
readonly status: JobStatus;
|
|
767
|
-
/** Last reported progress value (0-100). */
|
|
768
|
-
readonly progress: number;
|
|
769
|
-
/** Epoch timestamp of the last completed execution, if any. */
|
|
770
|
-
readonly lastRunAt?: number;
|
|
771
|
-
}
|
|
772
|
-
/**
|
|
773
|
-
* Manages the lifecycle of scheduled and manually-triggered jobs.
|
|
774
|
-
*
|
|
775
|
-
* Jobs are registered during bootstrap (via `@internal` {@link register}), then consumers
|
|
776
|
-
* interact through `start`, `stop`, `run`, and `cancel`. Scheduled jobs use Croner for
|
|
777
|
-
* cron-based timing; each execution receives a fresh {@link JobContext} for progress
|
|
778
|
-
* reporting and cooperative cancellation.
|
|
779
|
-
*
|
|
780
|
-
* @example
|
|
781
|
-
* ```ts
|
|
782
|
-
* // Start the cron scheduler for a registered job
|
|
783
|
-
* jobRegistry.start('data:cleanup');
|
|
784
|
-
*
|
|
785
|
-
* // Trigger an immediate (manual) execution
|
|
786
|
-
* await jobRegistry.run('data:cleanup');
|
|
787
|
-
*
|
|
788
|
-
* // Cancel a running execution cooperatively
|
|
789
|
-
* jobRegistry.cancel('data:cleanup');
|
|
790
|
-
*
|
|
791
|
-
* // Stop the cron scheduler and wait for any running execution to finish
|
|
792
|
-
* await jobRegistry.stop('data:cleanup');
|
|
793
|
-
* ```
|
|
794
|
-
*/
|
|
795
|
-
declare class JobRegistry {
|
|
796
|
-
private readonly jobs;
|
|
797
|
-
/** @internal Register a job definition during bootstrap. */
|
|
798
|
-
register(definition: JobDefinitionRecord): void;
|
|
799
|
-
/** Return a snapshot of all registered jobs and their current state. */
|
|
800
|
-
list(): readonly JobRuntimeState[];
|
|
801
|
-
/** Return the current state of a single job, or `undefined` if not registered. */
|
|
802
|
-
getStatus(jobId: string): JobRuntimeState | undefined;
|
|
803
|
-
/**
|
|
804
|
-
* Start the cron scheduler for a job if it is not already scheduled.
|
|
805
|
-
*
|
|
806
|
-
* Unlike {@link start}, this is idempotent and will not throw if the scheduler
|
|
807
|
-
* is already running.
|
|
808
|
-
*/
|
|
809
|
-
ensure(jobId: string): void;
|
|
810
|
-
/**
|
|
811
|
-
* Start the cron scheduler for a job.
|
|
812
|
-
*
|
|
813
|
-
* @throws {JobError} If the job already has an active scheduler.
|
|
814
|
-
*/
|
|
815
|
-
start(jobId: string): void;
|
|
816
|
-
/**
|
|
817
|
-
* Trigger an immediate (manual) execution of a job, bypassing the cron schedule.
|
|
923
|
+
* Register a handler for the given signal.
|
|
818
924
|
*
|
|
819
|
-
*
|
|
820
|
-
*
|
|
821
|
-
*/
|
|
822
|
-
run(jobId: string, ...args: unknown[]): Promise<unknown>;
|
|
823
|
-
/**
|
|
824
|
-
* Stop the cron scheduler and cancel any in-flight execution.
|
|
925
|
+
* The handler is bound to the current injection context at call time, so
|
|
926
|
+
* `inject()` resolves correctly even though the handler runs asynchronously.
|
|
825
927
|
*
|
|
826
|
-
*
|
|
827
|
-
* transitions to `"idle"` once fully stopped.
|
|
928
|
+
* @returns A dispose function that removes the subscription.
|
|
828
929
|
*/
|
|
829
|
-
|
|
930
|
+
subscribe<T>(signalId: string, handler: SignalListener<T>): () => void;
|
|
931
|
+
subscribe<T>(signalId: string, handler: ContextualSignalHandler<T>): () => void;
|
|
830
932
|
/**
|
|
831
|
-
*
|
|
933
|
+
* Publish a signal to all registered handlers.
|
|
832
934
|
*
|
|
833
|
-
*
|
|
834
|
-
*
|
|
935
|
+
* Handlers are invoked asynchronously via `queueMicrotask` and their errors are
|
|
936
|
+
* logged but never propagated to the publisher. The signal is also forwarded to
|
|
937
|
+
* any connected {@link PublicationRelay} listeners (e.g. renderer processes).
|
|
938
|
+
*
|
|
939
|
+
* @remarks Payload is optional for signals that carry no data (`SignalBus.publish<void>('app:ready')`).
|
|
835
940
|
*/
|
|
836
|
-
|
|
837
|
-
/** @internal */
|
|
838
|
-
|
|
839
|
-
private getJobOrThrow;
|
|
840
|
-
private startScheduler;
|
|
841
|
-
private executeJob;
|
|
941
|
+
publish<T = void>(signalId: string, payload?: T): void;
|
|
942
|
+
/** @internal Connect a relay listener (used by renderer registry). */
|
|
943
|
+
connectRelay(listener: SignalPublishListener): () => void;
|
|
842
944
|
}
|
|
843
945
|
//#endregion
|
|
844
|
-
//#region src/
|
|
946
|
+
//#region src/contracts/authoring.d.ts
|
|
845
947
|
/**
|
|
846
|
-
*
|
|
948
|
+
* Codegen contract types for `@electrojs/runtime`.
|
|
847
949
|
*
|
|
848
|
-
*
|
|
849
|
-
*
|
|
850
|
-
*
|
|
851
|
-
* access control.
|
|
950
|
+
* These interfaces and types are used by `@electrojs/codegen` to generate
|
|
951
|
+
* type-safe authoring APIs. The codegen augments the empty registry interfaces
|
|
952
|
+
* via `declare module "@electro"` to populate them with app-specific types.
|
|
852
953
|
*
|
|
853
|
-
* @
|
|
954
|
+
* @module contracts/authoring
|
|
854
955
|
*/
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
956
|
+
/** Maps `"moduleId:methodId"` to the method's type reference. Augmented by codegen. */
|
|
957
|
+
interface ModuleMethodMap {}
|
|
958
|
+
/** Maps module IDs to their method type objects. Augmented by codegen. */
|
|
959
|
+
interface ModuleApiRegistry {}
|
|
960
|
+
/** Maps signal keys to their payload types. Augmented by codegen. */
|
|
961
|
+
interface ModuleSignalPayloadMap {}
|
|
962
|
+
/** Maps module IDs to their job ID unions. Augmented by codegen. */
|
|
963
|
+
interface ModuleJobRegistry {}
|
|
964
|
+
/** Maps injectable class names to their class types. Augmented by codegen. */
|
|
965
|
+
interface InjectableClassRegistry {}
|
|
966
|
+
/** Maps window IDs to their `@Window()` class types. Augmented by codegen. */
|
|
967
|
+
interface WindowClassRegistry {}
|
|
968
|
+
/** Maps view IDs to their `@View()` class types. Augmented by codegen. */
|
|
969
|
+
interface ViewClassRegistry {}
|
|
970
|
+
/** Union of all registered module IDs. Derived from `ModuleApiRegistry` keys. */
|
|
971
|
+
type ModuleRegistryId = keyof ModuleApiRegistry;
|
|
972
|
+
type JobIdFor<TModuleId extends ModuleRegistryId> = Extract<ModuleJobRegistry[TModuleId], string>;
|
|
973
|
+
type SignalId = Extract<keyof ModuleSignalPayloadMap, string>;
|
|
974
|
+
type VoidSignalId = { [TKey in SignalId]: ModuleSignalPayloadMap[TKey] extends void ? TKey : never }[SignalId];
|
|
975
|
+
type NonVoidSignalId = Exclude<SignalId, VoidSignalId>;
|
|
976
|
+
/** A class decorated with `@Module()`. Used in generated registry arrays. */
|
|
977
|
+
type ModuleClass = Constructor;
|
|
978
|
+
/** A class decorated with `@View()`. Used in generated registry arrays. */
|
|
979
|
+
type ViewClass = Constructor;
|
|
980
|
+
/** A class decorated with `@Window()`. Used in generated registry arrays. */
|
|
981
|
+
type WindowClass = Constructor;
|
|
982
|
+
/**
|
|
983
|
+
* Shape of the static kernel definition object generated by codegen.
|
|
984
|
+
*
|
|
985
|
+
* Used by the generated `electroAppDefinition` constant which can be
|
|
986
|
+
* passed to `AppKernel.create()` for fully typed bootstrapping.
|
|
987
|
+
*/
|
|
988
|
+
interface AppKernelDefinition {
|
|
989
|
+
readonly root: Constructor;
|
|
990
|
+
readonly modules: readonly Constructor[];
|
|
991
|
+
readonly windows: readonly Constructor[];
|
|
992
|
+
readonly views: readonly Constructor[];
|
|
993
|
+
}
|
|
994
|
+
interface TypedSignalBus {
|
|
995
|
+
publish<TSignalId extends VoidSignalId>(signalId: TSignalId): void;
|
|
996
|
+
publish<TSignalId extends NonVoidSignalId>(signalId: TSignalId, payload: ModuleSignalPayloadMap[TSignalId]): void;
|
|
997
|
+
subscribe<TSignalId extends SignalId>(signalId: TSignalId, handler: SignalListener<ModuleSignalPayloadMap[TSignalId]>): () => void;
|
|
998
|
+
subscribe<TSignalId extends SignalId>(signalId: TSignalId, handler: ContextualSignalHandler<ModuleSignalPayloadMap[TSignalId]>): () => void;
|
|
999
|
+
}
|
|
1000
|
+
interface TypedJobRegistry<TJobId extends string = string> {
|
|
1001
|
+
ensure(jobId: TJobId): void;
|
|
1002
|
+
start(jobId: TJobId): void;
|
|
1003
|
+
run(jobId: TJobId, ...args: unknown[]): Promise<unknown>;
|
|
1004
|
+
stop(jobId: TJobId): Promise<void>;
|
|
1005
|
+
cancel(jobId: TJobId): void;
|
|
1006
|
+
getStatus(jobId: TJobId): JobRuntimeState | undefined;
|
|
1007
|
+
list(): readonly JobRuntimeState[];
|
|
871
1008
|
}
|
|
872
|
-
//#endregion
|
|
873
|
-
//#region src/desktop/renderer-registry.d.ts
|
|
874
1009
|
/**
|
|
875
|
-
*
|
|
1010
|
+
* Base type augmented onto module and provider classes by codegen.
|
|
876
1011
|
*
|
|
877
|
-
*
|
|
878
|
-
*
|
|
879
|
-
*
|
|
880
|
-
* communicates.
|
|
1012
|
+
* Codegen generates `interface MyModule extends ModuleAuthoringApi<"myModuleId"> {}`
|
|
1013
|
+
* which gives the class access to typed methods based on the module's registered
|
|
1014
|
+
* commands, queries, signals, and jobs.
|
|
881
1015
|
*
|
|
882
|
-
* @internal
|
|
883
1016
|
*/
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
* @throws {BridgeError} If the `viewId` does not match any registered view definition.
|
|
894
|
-
*/
|
|
895
|
-
getOrCreateSession(webContentsId: number, viewId: string): RendererSession;
|
|
896
|
-
/** Look up an existing session by its `webContentsId`, or `undefined` if none exists. */
|
|
897
|
-
getSession(webContentsId: number): RendererSession | undefined;
|
|
898
|
-
/** Remove a session when its renderer process is destroyed. */
|
|
899
|
-
removeSession(webContentsId: number): void;
|
|
900
|
-
/** Return all active renderer sessions. */
|
|
901
|
-
getAllSessions(): readonly RendererSession[];
|
|
1017
|
+
interface ModuleAuthoringApi<TModuleId extends ModuleRegistryId> {
|
|
1018
|
+
readonly moduleId: TModuleId;
|
|
1019
|
+
readonly api: ModuleApiRegistry[TModuleId];
|
|
1020
|
+
readonly signals: TypedSignalBus;
|
|
1021
|
+
readonly jobs: TypedJobRegistry<JobIdFor<TModuleId>>;
|
|
1022
|
+
readonly modules: ModuleRegistry;
|
|
1023
|
+
readonly windows: WindowManager;
|
|
1024
|
+
readonly views: ViewManager;
|
|
1025
|
+
readonly logger: ElectroLogger;
|
|
902
1026
|
}
|
|
903
|
-
//#endregion
|
|
904
|
-
//#region src/desktop/view-manager.d.ts
|
|
905
1027
|
/**
|
|
906
|
-
*
|
|
1028
|
+
* Base type augmented onto `@Window()` classes by codegen.
|
|
907
1029
|
*
|
|
908
|
-
*
|
|
909
|
-
*
|
|
910
|
-
|
|
1030
|
+
* Provides typed window management capabilities when extended by codegen-generated
|
|
1031
|
+
* interface augmentations.
|
|
1032
|
+
*/
|
|
1033
|
+
interface WindowAuthoringApi extends WindowAuthoringSurface {
|
|
1034
|
+
readonly logger: ElectroLogger;
|
|
1035
|
+
}
|
|
1036
|
+
/**
|
|
1037
|
+
* Base type augmented onto `@View()` classes by codegen.
|
|
911
1038
|
*
|
|
912
|
-
*
|
|
1039
|
+
* Provides typed view management capabilities when extended by codegen-generated
|
|
1040
|
+
* interface augmentations.
|
|
913
1041
|
*/
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
/**
|
|
917
|
-
* Register a view provider and apply its `@View()` source URL.
|
|
918
|
-
*
|
|
919
|
-
* @remarks Silently skips providers that do not have view metadata.
|
|
920
|
-
*/
|
|
921
|
-
register(providerRef: ProviderRef): void;
|
|
922
|
-
/** Look up a registered view provider by its view ID. */
|
|
923
|
-
get(viewId: string): ProviderRef | undefined;
|
|
924
|
-
/** Return all registered view providers. */
|
|
925
|
-
list(): readonly ProviderRef[];
|
|
926
|
-
/** Clear the registry. Does not destroy any underlying web contents. */
|
|
927
|
-
dispose(): Promise<void>;
|
|
1042
|
+
interface ViewAuthoringApi extends ViewAuthoringSurface {
|
|
1043
|
+
readonly logger: ElectroLogger;
|
|
928
1044
|
}
|
|
929
1045
|
//#endregion
|
|
930
|
-
//#region src/
|
|
931
|
-
declare const VIEW_STATE: unique symbol;
|
|
932
|
-
interface ViewAuthoringSurface {
|
|
933
|
-
readonly contentView: WebContentsView | undefined;
|
|
934
|
-
readonly webContents: WebContents | undefined;
|
|
935
|
-
load(): Promise<void>;
|
|
936
|
-
setBounds(bounds: Rectangle): void;
|
|
937
|
-
setBackgroundColor(color: string): void;
|
|
938
|
-
focus(): void;
|
|
939
|
-
setWindowButtonVisibility(visible: boolean): void;
|
|
940
|
-
}
|
|
1046
|
+
//#region src/container/inject.d.ts
|
|
941
1047
|
/**
|
|
942
|
-
*
|
|
1048
|
+
* Resolve a dependency from the current injection context.
|
|
943
1049
|
*
|
|
944
|
-
*
|
|
945
|
-
*
|
|
946
|
-
*
|
|
1050
|
+
* This is the primary way framework-managed classes obtain their dependencies.
|
|
1051
|
+
* It reads the active {@link Injector} from `AsyncLocalStorage` and delegates to
|
|
1052
|
+
* {@link Injector.get}.
|
|
947
1053
|
*
|
|
948
|
-
*
|
|
949
|
-
* `
|
|
1054
|
+
* @remarks
|
|
1055
|
+
* `inject()` is only available inside a framework-managed execution scope:
|
|
1056
|
+
* - **Construction** -- property initializers of `@Injectable()`, `@Module()`, `@View()`, or `@Window()` classes
|
|
1057
|
+
* - **Lifecycle hooks** -- `onInit`, `onStart`, `onReady`, `onShutdown`, `onDispose`
|
|
1058
|
+
* - **Capability handlers** -- methods decorated with `@command`, `@query`, `@signal`, or `@job`
|
|
950
1059
|
*
|
|
951
|
-
*
|
|
1060
|
+
* Calling it anywhere else (e.g. in a `setTimeout` callback or a plain function)
|
|
1061
|
+
* throws {@link DIError} with code `ELECTRO_DI_NO_INJECTION_CONTEXT`.
|
|
952
1062
|
*
|
|
953
1063
|
* @example
|
|
954
1064
|
* ```ts
|
|
955
|
-
* @
|
|
956
|
-
* class
|
|
957
|
-
*
|
|
958
|
-
* await this.load();
|
|
959
|
-
* this.setBounds({ x: 0, y: 0, width: 800, height: 600 });
|
|
960
|
-
* }
|
|
1065
|
+
* @Injectable()
|
|
1066
|
+
* class MyService {
|
|
1067
|
+
* private readonly config = inject(AppConfig);
|
|
961
1068
|
* }
|
|
962
1069
|
* ```
|
|
1070
|
+
*
|
|
1071
|
+
* @throws {@link DIError} if no injection context is active or the token cannot be resolved.
|
|
963
1072
|
*/
|
|
964
|
-
declare
|
|
965
|
-
private [VIEW_STATE];
|
|
966
|
-
/** The underlying Electron `WebContentsView`, or `undefined` if not yet created. */
|
|
967
|
-
get contentView(): WebContentsView | undefined;
|
|
968
|
-
/** The `WebContents` associated with this view, or `undefined` if not yet created. */
|
|
969
|
-
get webContents(): WebContents | undefined;
|
|
970
|
-
/**
|
|
971
|
-
* Create the underlying `WebContentsView` (if needed) and load the configured source URL.
|
|
972
|
-
*
|
|
973
|
-
* The view is lazily created on the first call. Subsequent calls reload the source.
|
|
974
|
-
* If the previous view was destroyed (e.g. parent window closed), a new one is created.
|
|
975
|
-
* No-ops if no source URL has been configured.
|
|
976
|
-
*/
|
|
977
|
-
load(): Promise<void>;
|
|
978
|
-
/** Set the position and size of this view within its parent window. */
|
|
979
|
-
setBounds(bounds: Rectangle): void;
|
|
980
|
-
/** Set the background color of the view (e.g. `"#ffffff"` or `"transparent"`). */
|
|
981
|
-
setBackgroundColor(color: string): void;
|
|
982
|
-
/** Give keyboard focus to this view's web contents. */
|
|
983
|
-
focus(): void;
|
|
984
|
-
/** Show or hide the native window traffic-light buttons for this view (macOS). */
|
|
985
|
-
setWindowButtonVisibility(visible: boolean): void;
|
|
986
|
-
private createView;
|
|
987
|
-
private static resolveSource;
|
|
988
|
-
/** @internal Called by the framework to set the view source from @View metadata. */
|
|
989
|
-
static __setSource(instance: ViewProvider, source: string): void;
|
|
990
|
-
/** @internal Called by the framework to set web preferences from @View metadata. */
|
|
991
|
-
static __setWebPreferences(instance: ViewProvider, webPreferences: WebPreferences): void;
|
|
992
|
-
}
|
|
1073
|
+
declare function inject<T>(token: InjectionToken<T>): T extends SignalBus ? TypedSignalBus : T;
|
|
993
1074
|
//#endregion
|
|
994
|
-
//#region src/
|
|
1075
|
+
//#region src/container/injection-context.d.ts
|
|
995
1076
|
/**
|
|
996
|
-
*
|
|
1077
|
+
* Ambient injection context backed by `AsyncLocalStorage`.
|
|
997
1078
|
*
|
|
998
|
-
*
|
|
999
|
-
*
|
|
1000
|
-
*
|
|
1079
|
+
* The framework uses `InjectionContext` to make the current {@link Injector} available
|
|
1080
|
+
* to {@link inject} calls without requiring explicit injector references. It is set
|
|
1081
|
+
* automatically during provider construction, lifecycle hooks, and capability handlers.
|
|
1082
|
+
*
|
|
1083
|
+
* @remarks
|
|
1084
|
+
* This is a framework-internal API. Application code should use {@link inject} instead
|
|
1085
|
+
* of interacting with `InjectionContext` directly.
|
|
1001
1086
|
*
|
|
1002
1087
|
* @internal
|
|
1003
1088
|
*/
|
|
1004
|
-
declare
|
|
1005
|
-
private readonly windows;
|
|
1089
|
+
declare const InjectionContext: {
|
|
1006
1090
|
/**
|
|
1007
|
-
*
|
|
1008
|
-
*
|
|
1009
|
-
* @remarks Silently skips providers that do not have window metadata.
|
|
1091
|
+
* Execute `fn` within the scope of the given injector.
|
|
1092
|
+
* Any {@link inject} call made synchronously inside `fn` will resolve from this injector.
|
|
1010
1093
|
*/
|
|
1011
|
-
|
|
1012
|
-
/**
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1094
|
+
readonly run: <T>(injector: Injector, fn: () => T) => T;
|
|
1095
|
+
/**
|
|
1096
|
+
* Execute `fn` within the scope of the given injector, additionally tracking `owner`
|
|
1097
|
+
* as the object currently being constructed or invoked.
|
|
1098
|
+
*/
|
|
1099
|
+
readonly runOwned: <T>(injector: Injector, owner: object, fn: () => T) => T; /** Return the injector for the current execution context, or `undefined` if none is active. */
|
|
1100
|
+
readonly current: () => Injector | undefined; /** Return the owner object of the current execution context, or `undefined` if not set. */
|
|
1101
|
+
readonly currentOwner: () => object | undefined; /** Whether a framework-managed injection context is currently active. */
|
|
1102
|
+
readonly isActive: () => boolean;
|
|
1103
|
+
};
|
|
1019
1104
|
//#endregion
|
|
1020
|
-
//#region src/
|
|
1021
|
-
declare const WINDOW_STATE: unique symbol;
|
|
1022
|
-
interface WindowAuthoringSurface {
|
|
1023
|
-
readonly window: BaseWindow | undefined;
|
|
1024
|
-
create(): void;
|
|
1025
|
-
mount(view: Pick<ViewProvider, "contentView">): void;
|
|
1026
|
-
show(): void;
|
|
1027
|
-
hide(): void;
|
|
1028
|
-
focus(): void;
|
|
1029
|
-
close(): void;
|
|
1030
|
-
getBounds(): Rectangle | undefined;
|
|
1031
|
-
}
|
|
1105
|
+
//#region src/modules/validator.d.ts
|
|
1032
1106
|
/**
|
|
1033
|
-
*
|
|
1107
|
+
* Validates a scanned {@link AppDefinition} for structural correctness before bootstrap.
|
|
1034
1108
|
*
|
|
1035
|
-
*
|
|
1036
|
-
*
|
|
1037
|
-
*
|
|
1109
|
+
* Checks performed:
|
|
1110
|
+
* - Unique module IDs
|
|
1111
|
+
* - Exports reference declared providers
|
|
1112
|
+
* - No cyclic module imports
|
|
1113
|
+
* - Unique view/window IDs
|
|
1114
|
+
* - Unique bridge channel names
|
|
1115
|
+
* - Unique job IDs
|
|
1116
|
+
* - Provider role exclusivity (a class cannot be both a view and a window)
|
|
1117
|
+
* - View access references point to existing bridge channels
|
|
1038
1118
|
*
|
|
1039
|
-
* @
|
|
1040
|
-
|
|
1041
|
-
|
|
1119
|
+
* @throws {BootstrapError} On the first validation failure encountered.
|
|
1120
|
+
*/
|
|
1121
|
+
declare function validateAppDefinition(definition: AppDefinition): void;
|
|
1122
|
+
//#endregion
|
|
1123
|
+
//#region src/desktop/renderer-session.d.ts
|
|
1124
|
+
/**
|
|
1125
|
+
* Tracks the capabilities of a single renderer process (identified by `webContentsId`).
|
|
1042
1126
|
*
|
|
1043
|
-
*
|
|
1044
|
-
*
|
|
1045
|
-
* @
|
|
1046
|
-
*
|
|
1047
|
-
*
|
|
1048
|
-
*
|
|
1049
|
-
* this.mount(this.mainView);
|
|
1050
|
-
* this.show();
|
|
1051
|
-
* }
|
|
1052
|
-
* }
|
|
1053
|
-
* ```
|
|
1127
|
+
* Each session records which bridge channels the renderer may invoke and which signals
|
|
1128
|
+
* it is allowed to receive, as declared in the `@View()` decorator metadata. The
|
|
1129
|
+
* {@link BridgeAccessGuard} and signal relay use this information to enforce per-view
|
|
1130
|
+
* access control.
|
|
1131
|
+
*
|
|
1132
|
+
* @internal Created and managed by {@link RendererRegistry}.
|
|
1054
1133
|
*/
|
|
1055
|
-
declare
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1134
|
+
declare class RendererSession {
|
|
1135
|
+
/** The Electron `webContents.id` that uniquely identifies this renderer process. */
|
|
1136
|
+
readonly rendererId: number;
|
|
1137
|
+
/** The view ID this renderer is associated with. */
|
|
1138
|
+
readonly viewId: string;
|
|
1139
|
+
/** Set of bridge channel names this renderer is allowed to invoke. */
|
|
1140
|
+
readonly access: ReadonlySet<string>;
|
|
1141
|
+
/** Set of signal IDs this renderer is allowed to receive. */
|
|
1142
|
+
readonly allowedSignals: ReadonlySet<string>;
|
|
1143
|
+
constructor(/** The Electron `webContents.id` that uniquely identifies this renderer process. */
|
|
1144
|
+
|
|
1145
|
+
rendererId: number, viewDef: ViewDefinition);
|
|
1146
|
+
/** Check whether this renderer has access to the given bridge channel. */
|
|
1147
|
+
hasAccess(channel: string): boolean;
|
|
1148
|
+
/** Check whether this renderer is allowed to receive the given signal. */
|
|
1149
|
+
canReceiveSignal(signalId: string): boolean;
|
|
1150
|
+
}
|
|
1151
|
+
//#endregion
|
|
1152
|
+
//#region src/desktop/renderer-registry.d.ts
|
|
1153
|
+
/**
|
|
1154
|
+
* Maps Electron `webContentsId` values to {@link RendererSession} instances.
|
|
1155
|
+
*
|
|
1156
|
+
* Used by the bridge layer to look up which renderer process is making an IPC request
|
|
1157
|
+
* and determine what channels and signals it is allowed to access. View definitions are
|
|
1158
|
+
* registered at bootstrap time; sessions are created lazily when a renderer first
|
|
1159
|
+
* communicates.
|
|
1160
|
+
*
|
|
1161
|
+
* @internal
|
|
1162
|
+
*/
|
|
1163
|
+
declare class RendererRegistry {
|
|
1164
|
+
private readonly sessions;
|
|
1165
|
+
private readonly viewDefinitions;
|
|
1166
|
+
/** Store a view definition so that sessions can be created for it later. */
|
|
1167
|
+
registerView(viewDef: ViewDefinition): void;
|
|
1061
1168
|
/**
|
|
1062
|
-
*
|
|
1169
|
+
* Return the existing session for a `webContentsId`, or create one if this is
|
|
1170
|
+
* the first request from that renderer.
|
|
1063
1171
|
*
|
|
1064
|
-
*
|
|
1065
|
-
* No-ops silently if the window or view has not been created yet.
|
|
1172
|
+
* @throws {BridgeError} If the `viewId` does not match any registered view definition.
|
|
1066
1173
|
*/
|
|
1067
|
-
|
|
1068
|
-
/**
|
|
1069
|
-
|
|
1070
|
-
/**
|
|
1071
|
-
|
|
1072
|
-
/**
|
|
1073
|
-
|
|
1074
|
-
/** Close and destroy the native window, releasing its resources. */
|
|
1075
|
-
close(): void;
|
|
1076
|
-
/** Return the window's current screen bounds, or `undefined` if not created. */
|
|
1077
|
-
getBounds(): Rectangle | undefined;
|
|
1078
|
-
/** @internal Called by the framework to set the window configuration from @Window metadata. */
|
|
1079
|
-
static __setConfiguration(instance: WindowProvider, configuration?: BaseWindowConstructorOptions): void;
|
|
1174
|
+
getOrCreateSession(webContentsId: number, viewId: string): RendererSession;
|
|
1175
|
+
/** Look up an existing session by its `webContentsId`, or `undefined` if none exists. */
|
|
1176
|
+
getSession(webContentsId: number): RendererSession | undefined;
|
|
1177
|
+
/** Remove a session when its renderer process is destroyed. */
|
|
1178
|
+
removeSession(webContentsId: number): void;
|
|
1179
|
+
/** Return all active renderer sessions. */
|
|
1180
|
+
getAllSessions(): readonly RendererSession[];
|
|
1080
1181
|
}
|
|
1081
1182
|
//#endregion
|
|
1082
1183
|
//#region src/bridge/access-guard.d.ts
|
|
@@ -1397,103 +1498,4 @@ declare class SignalError extends RuntimeError {
|
|
|
1397
1498
|
static invalidSignalId(signalId: unknown): SignalError;
|
|
1398
1499
|
}
|
|
1399
1500
|
//#endregion
|
|
1400
|
-
//#region src/contracts/authoring.d.ts
|
|
1401
|
-
/**
|
|
1402
|
-
* Codegen contract types for `@electrojs/runtime`.
|
|
1403
|
-
*
|
|
1404
|
-
* These interfaces and types are used by `@electrojs/codegen` to generate
|
|
1405
|
-
* type-safe authoring APIs. The codegen augments the empty registry interfaces
|
|
1406
|
-
* via `declare module "@electro"` to populate them with app-specific types.
|
|
1407
|
-
*
|
|
1408
|
-
* @module contracts/authoring
|
|
1409
|
-
*/
|
|
1410
|
-
/** Maps `"moduleId:methodId"` to the method's type reference. Augmented by codegen. */
|
|
1411
|
-
interface ModuleMethodMap {}
|
|
1412
|
-
/** Maps module IDs to their method type objects. Augmented by codegen. */
|
|
1413
|
-
interface ModuleApiRegistry {}
|
|
1414
|
-
/** Maps signal keys to their payload types. Augmented by codegen. */
|
|
1415
|
-
interface ModuleSignalPayloadMap {}
|
|
1416
|
-
/** Maps module IDs to their job ID unions. Augmented by codegen. */
|
|
1417
|
-
interface ModuleJobRegistry {}
|
|
1418
|
-
/** Maps injectable class names to their class types. Augmented by codegen. */
|
|
1419
|
-
interface InjectableClassRegistry {}
|
|
1420
|
-
/** Maps window IDs to their `@Window()` class types. Augmented by codegen. */
|
|
1421
|
-
interface WindowClassRegistry {}
|
|
1422
|
-
/** Maps view IDs to their `@View()` class types. Augmented by codegen. */
|
|
1423
|
-
interface ViewClassRegistry {}
|
|
1424
|
-
/** Union of all registered module IDs. Derived from `ModuleApiRegistry` keys. */
|
|
1425
|
-
type ModuleRegistryId = keyof ModuleApiRegistry;
|
|
1426
|
-
type JobIdFor<TModuleId extends ModuleRegistryId> = Extract<ModuleJobRegistry[TModuleId], string>;
|
|
1427
|
-
type SignalId = Extract<keyof ModuleSignalPayloadMap, string>;
|
|
1428
|
-
type VoidSignalId = { [TKey in SignalId]: ModuleSignalPayloadMap[TKey] extends void ? TKey : never }[SignalId];
|
|
1429
|
-
type NonVoidSignalId = Exclude<SignalId, VoidSignalId>;
|
|
1430
|
-
/** A class decorated with `@Module()`. Used in generated registry arrays. */
|
|
1431
|
-
type ModuleClass = Constructor;
|
|
1432
|
-
/** A class decorated with `@View()`. Used in generated registry arrays. */
|
|
1433
|
-
type ViewClass = Constructor;
|
|
1434
|
-
/** A class decorated with `@Window()`. Used in generated registry arrays. */
|
|
1435
|
-
type WindowClass = Constructor;
|
|
1436
|
-
/**
|
|
1437
|
-
* Shape of the static kernel definition object generated by codegen.
|
|
1438
|
-
*
|
|
1439
|
-
* Used by the generated `electroAppDefinition` constant which can be
|
|
1440
|
-
* passed to `AppKernel.create()` for fully typed bootstrapping.
|
|
1441
|
-
*/
|
|
1442
|
-
interface AppKernelDefinition {
|
|
1443
|
-
readonly root: Constructor;
|
|
1444
|
-
readonly modules: readonly Constructor[];
|
|
1445
|
-
readonly windows: readonly Constructor[];
|
|
1446
|
-
readonly views: readonly Constructor[];
|
|
1447
|
-
}
|
|
1448
|
-
interface TypedSignalBus {
|
|
1449
|
-
publish<TSignalId extends VoidSignalId>(signalId: TSignalId): void;
|
|
1450
|
-
publish<TSignalId extends NonVoidSignalId>(signalId: TSignalId, payload: ModuleSignalPayloadMap[TSignalId]): void;
|
|
1451
|
-
subscribe<TSignalId extends SignalId>(signalId: TSignalId, handler: SignalHandler<ModuleSignalPayloadMap[TSignalId]>): () => void;
|
|
1452
|
-
}
|
|
1453
|
-
interface TypedJobRegistry<TJobId extends string = string> {
|
|
1454
|
-
ensure(jobId: TJobId): void;
|
|
1455
|
-
start(jobId: TJobId): void;
|
|
1456
|
-
run(jobId: TJobId, ...args: unknown[]): Promise<unknown>;
|
|
1457
|
-
stop(jobId: TJobId): Promise<void>;
|
|
1458
|
-
cancel(jobId: TJobId): void;
|
|
1459
|
-
getStatus(jobId: TJobId): JobRuntimeState | undefined;
|
|
1460
|
-
list(): readonly JobRuntimeState[];
|
|
1461
|
-
}
|
|
1462
|
-
/**
|
|
1463
|
-
* Base type augmented onto module and provider classes by codegen.
|
|
1464
|
-
*
|
|
1465
|
-
* Codegen generates `interface MyModule extends ModuleAuthoringApi<"myModuleId"> {}`
|
|
1466
|
-
* which gives the class access to typed methods based on the module's registered
|
|
1467
|
-
* commands, queries, signals, and jobs.
|
|
1468
|
-
*
|
|
1469
|
-
*/
|
|
1470
|
-
interface ModuleAuthoringApi<TModuleId extends ModuleRegistryId> {
|
|
1471
|
-
readonly moduleId: TModuleId;
|
|
1472
|
-
readonly api: ModuleApiRegistry[TModuleId];
|
|
1473
|
-
readonly signals: TypedSignalBus;
|
|
1474
|
-
readonly jobs: TypedJobRegistry<JobIdFor<TModuleId>>;
|
|
1475
|
-
readonly modules: ModuleRegistry;
|
|
1476
|
-
readonly windows: WindowManager;
|
|
1477
|
-
readonly views: ViewManager;
|
|
1478
|
-
readonly logger: ElectroLogger;
|
|
1479
|
-
}
|
|
1480
|
-
/**
|
|
1481
|
-
* Base type augmented onto `@Window()` classes by codegen.
|
|
1482
|
-
*
|
|
1483
|
-
* Provides typed window management capabilities when extended by codegen-generated
|
|
1484
|
-
* interface augmentations.
|
|
1485
|
-
*/
|
|
1486
|
-
interface WindowAuthoringApi extends WindowAuthoringSurface {
|
|
1487
|
-
readonly logger: ElectroLogger;
|
|
1488
|
-
}
|
|
1489
|
-
/**
|
|
1490
|
-
* Base type augmented onto `@View()` classes by codegen.
|
|
1491
|
-
*
|
|
1492
|
-
* Provides typed view management capabilities when extended by codegen-generated
|
|
1493
|
-
* interface augmentations.
|
|
1494
|
-
*/
|
|
1495
|
-
interface ViewAuthoringApi extends ViewAuthoringSurface {
|
|
1496
|
-
readonly logger: ElectroLogger;
|
|
1497
|
-
}
|
|
1498
|
-
//#endregion
|
|
1499
1501
|
export { type AppDefinition, AppKernel, type AppKernelDefinition, type AppKernelOptions, BootstrapError, BridgeAccessGuard, type BridgeClientConfig, BridgeDispatcher, BridgeError, BridgeHandler, type BridgeMethodDefinition, type BridgeMethodKind, type BridgeRequest, type BridgeResponse, type ContextualSignalHandler, DIError, type ElectroIpcRenderer, type ElectroLogBindings, type ElectroLogContext, type ElectroLogLevel, type ElectroLogger, IPC_CHANNELS, type InjectableClassRegistry, InjectionContext, Injector, JobContext, type JobDefinition, JobError, JobRegistry, type JobRuntimeState, type JobStatus, type KernelState, LifecycleError, type LifecycleTarget, type ModuleApiRegistry, type ModuleAuthoringApi, type ModuleClass, type ModuleDefinition, type ModuleJobRegistry, type ModuleMethodMap, ModuleRef, ModuleRegistry, type ModuleRegistryId, type ModuleSignalPayloadMap, type ModuleSnapshot, type ModuleStatus, type PreloadBridgeApi, type ProviderDefinition, type ProviderKind, ProviderRef, type ProviderSnapshot, RendererRegistry, RendererSession, RuntimeError, SignalBus, SignalContext, SignalError, type SignalHandler, type SignalHandlerDefinition, type SignalListener, type TypedJobRegistry, type TypedSignalBus, type ViewAuthoringApi, type ViewClass, type ViewClassRegistry, type ViewDefinition, ViewManager, ViewProvider, type WindowAuthoringApi, type WindowClass, type WindowClassRegistry, type WindowDefinition, WindowManager, WindowProvider, createBridgeClient, createConsoleLogger, inject, scanModules, serializeBridgeError, validateAppDefinition };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@electrojs/runtime",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "Electron main-process runtime for ElectroJS with DI, lifecycle hooks, typed IPC, and jobs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dependency-injection",
|
|
@@ -49,12 +49,12 @@
|
|
|
49
49
|
"publint": "^0.3.18",
|
|
50
50
|
"tsdown": "^0.21.4",
|
|
51
51
|
"vitest": "^4.1.1",
|
|
52
|
-
"@electrojs/common": "1.0.
|
|
53
|
-
"@electrojs/config": "1.0.
|
|
52
|
+
"@electrojs/common": "1.0.9",
|
|
53
|
+
"@electrojs/config": "1.0.9"
|
|
54
54
|
},
|
|
55
55
|
"peerDependencies": {
|
|
56
|
-
"@electrojs/common": "1.0.
|
|
57
|
-
"@electrojs/config": "1.0.
|
|
56
|
+
"@electrojs/common": "1.0.9",
|
|
57
|
+
"@electrojs/config": "1.0.9",
|
|
58
58
|
"@types/node": "^25.5.0",
|
|
59
59
|
"electron": ">=41"
|
|
60
60
|
},
|