@cordy/electro 1.1.3 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +18 -39
- package/dist/index.mjs +70 -84
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseWindow, BaseWindowConstructorOptions, WebContentsView
|
|
1
|
+
import { BaseWindow, BaseWindowConstructorOptions, WebContentsView } from "electron";
|
|
2
2
|
import { UserConfig } from "vite";
|
|
3
3
|
|
|
4
4
|
//#region src/core/feature/enums.d.ts
|
|
@@ -18,25 +18,18 @@ declare enum FeatureStatus {
|
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region src/core/view/types.d.ts
|
|
20
20
|
type ViewId = string;
|
|
21
|
-
/**
|
|
22
|
-
interface
|
|
21
|
+
/** Runtime view registry entry — injected by CLI via __ELECTRO_VIEW_REGISTRY__. */
|
|
22
|
+
interface ViewRegistryEntry {
|
|
23
23
|
id: ViewId;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
webPreferences?: WebPreferences;
|
|
27
|
-
}
|
|
28
|
-
/** Config for dynamic views (no renderer entry, programmatic). */
|
|
29
|
-
interface DynamicViewConfig {
|
|
30
|
-
id: ViewId;
|
|
31
|
-
webPreferences?: WebPreferences;
|
|
24
|
+
hasRenderer: boolean;
|
|
25
|
+
webPreferences?: Record<string, unknown>;
|
|
32
26
|
}
|
|
33
|
-
type ViewConfig = RendererViewConfig | DynamicViewConfig;
|
|
34
27
|
/** A WebContentsView augmented with `load()` for renderer-linked views. */
|
|
35
28
|
type ElectroView = WebContentsView & {
|
|
36
29
|
load(): Promise<void>;
|
|
37
30
|
};
|
|
38
31
|
/** Public interface — hides the View class. */
|
|
39
|
-
interface
|
|
32
|
+
interface ViewInstance {
|
|
40
33
|
readonly id: ViewId;
|
|
41
34
|
/** Create the WebContentsView. Idempotent: returns existing if alive. */
|
|
42
35
|
create(): ElectroView;
|
|
@@ -45,13 +38,6 @@ interface CreatedView {
|
|
|
45
38
|
/** Destroy the WebContentsView and clear refs. */
|
|
46
39
|
destroy(): void;
|
|
47
40
|
}
|
|
48
|
-
/** Type-erased interface for managers. */
|
|
49
|
-
interface ViewInstance {
|
|
50
|
-
readonly id: ViewId;
|
|
51
|
-
create(): ElectroView;
|
|
52
|
-
view(): ElectroView | null;
|
|
53
|
-
destroy(): void;
|
|
54
|
-
}
|
|
55
41
|
//#endregion
|
|
56
42
|
//#region src/core/view/manager.d.ts
|
|
57
43
|
/**
|
|
@@ -74,24 +60,28 @@ interface WindowConfig<TApi = void> {
|
|
|
74
60
|
options?: BaseWindowConstructorOptions;
|
|
75
61
|
api?: (window: BaseWindow) => TApi;
|
|
76
62
|
}
|
|
77
|
-
/**
|
|
78
|
-
interface
|
|
63
|
+
/** Base window interface (without API methods). */
|
|
64
|
+
interface WindowBase {
|
|
79
65
|
readonly id: WindowId;
|
|
80
66
|
/** Create the BaseWindow. Idempotent: returns existing if alive. */
|
|
81
67
|
create(): BaseWindow;
|
|
82
68
|
/** The live BaseWindow, or null if not yet created / destroyed. */
|
|
83
69
|
readonly window: BaseWindow | null;
|
|
84
|
-
/** The typed API, or null if not yet created / destroyed. */
|
|
85
|
-
readonly api: TApi | null;
|
|
86
70
|
/** Destroy the BaseWindow and clear refs. */
|
|
87
71
|
destroy(): void;
|
|
88
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Public interface — API methods are mixed directly onto the object.
|
|
75
|
+
* Access API methods directly: `window.show()` instead of `window.api?.show()`.
|
|
76
|
+
*/
|
|
77
|
+
type CreatedWindow<TApi = void> = WindowBase & (TApi extends void ? {} : TApi) & {
|
|
78
|
+
/** @internal Phantom type for API type inference. */readonly __apiType?: TApi;
|
|
79
|
+
};
|
|
89
80
|
/** Type-erased interface for managers. */
|
|
90
81
|
interface WindowInstance {
|
|
91
82
|
readonly id: WindowId;
|
|
92
83
|
create(): BaseWindow;
|
|
93
84
|
readonly window: BaseWindow | null;
|
|
94
|
-
readonly api: unknown;
|
|
95
85
|
destroy(): void;
|
|
96
86
|
}
|
|
97
87
|
//#endregion
|
|
@@ -631,7 +621,7 @@ interface RuntimeDefinition {
|
|
|
631
621
|
interface ViewDefinition {
|
|
632
622
|
readonly [VIEW_BRAND]: true;
|
|
633
623
|
readonly name: string;
|
|
634
|
-
readonly entry
|
|
624
|
+
readonly entry?: string;
|
|
635
625
|
readonly features?: readonly string[];
|
|
636
626
|
readonly vite?: UserConfig;
|
|
637
627
|
readonly preload?: string;
|
|
@@ -652,7 +642,7 @@ interface DefineRuntimeInput {
|
|
|
652
642
|
type SuggestFeatureId = (keyof FeatureMap & string) | (string & {});
|
|
653
643
|
interface DefineViewInput {
|
|
654
644
|
name: string;
|
|
655
|
-
entry
|
|
645
|
+
entry?: string;
|
|
656
646
|
features?: readonly SuggestFeatureId[];
|
|
657
647
|
vite?: UserConfig;
|
|
658
648
|
preload?: string;
|
|
@@ -743,7 +733,6 @@ declare class Logger implements LoggerContext {
|
|
|
743
733
|
type RuntimeConfig = {
|
|
744
734
|
features?: FeatureConfig<any>[];
|
|
745
735
|
windows?: WindowInstance[];
|
|
746
|
-
views?: ViewInstance[];
|
|
747
736
|
logger?: {
|
|
748
737
|
handlers?: LogHandler[];
|
|
749
738
|
};
|
|
@@ -793,16 +782,6 @@ declare function createTask<TId extends TaskId, TPayload = void>(config: TaskCon
|
|
|
793
782
|
*/
|
|
794
783
|
declare function createWindow<TApi = void>(config: WindowConfig<TApi>): CreatedWindow<TApi>;
|
|
795
784
|
//#endregion
|
|
796
|
-
//#region src/core/view/helpers.d.ts
|
|
797
|
-
/**
|
|
798
|
-
* Creates a {@link View} instance from a configuration object.
|
|
799
|
-
*
|
|
800
|
-
* @param config - View configuration with `id`, and either `renderer` (for Vite-built views) or `webPreferences` (for dynamic views).
|
|
801
|
-
* @returns A new `View` instance ready for registration.
|
|
802
|
-
* @throws If `config.id` is empty.
|
|
803
|
-
*/
|
|
804
|
-
declare function createView(config: ViewConfig): CreatedView;
|
|
805
|
-
//#endregion
|
|
806
785
|
//#region src/policy/types.d.ts
|
|
807
786
|
/** Outcome of a policy check. */
|
|
808
787
|
declare enum PolicyDecision {
|
|
@@ -841,4 +820,4 @@ declare class PolicyEngine {
|
|
|
841
820
|
getViewNames(): string[];
|
|
842
821
|
}
|
|
843
822
|
//#endregion
|
|
844
|
-
export { type BaseContext, type CreatedEvent, type CreatedService, type CreatedTask, type
|
|
823
|
+
export { type BaseContext, type CreatedEvent, type CreatedService, type CreatedTask, type CreatedWindow, type DefineConfigInput, type DefineRuntimeInput, type DefineViewInput, type ElectroConfig, type ElectroView, EventAccessor, type EventHandler, type EventId, type EventInstance, type EventSubscription, type FeatureConfig, type FeatureContext, type FeatureHandle, type FeatureId, type FeatureMap, FeatureStatus, type LogEntry, type LogHandler, type LoggerContext, PolicyDecision, PolicyEngine, type PolicyResult, Runtime, type RuntimeConfig, type RuntimeDefinition, RuntimeState, type ServiceConfig, type ServiceId, type ServiceInfo, type ServiceOwnerMap, ServiceScope, ServiceStatus, type StopMode, type TaskConfig, type TaskExecutionContext, type TaskHandle, type TaskId, TaskOverlapStrategy, type TaskOwnerMap, TaskRetryStrategy, TaskStatus, type TaskStatusInfo, type TypedContext, type ViewDefinition, type ViewId, type ViewInstance, type ViewMap, type ViewRegistryEntry, type WindowApiMap, type WindowConfig, type WindowId, type WindowInstance, createEvent, createFeature, createRuntime, createService, createTask, createWindow, defineConfig, defineRuntime, defineView };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
|
-
import { Cron } from "croner";
|
|
3
2
|
import { join } from "node:path";
|
|
3
|
+
import { Cron } from "croner";
|
|
4
4
|
|
|
5
5
|
//#region \0rolldown/runtime.js
|
|
6
6
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
@@ -58,7 +58,6 @@ const VIEW_NAME_PATTERN = /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/;
|
|
|
58
58
|
function defineView(input) {
|
|
59
59
|
if (!input.name || input.name.trim().length === 0) throw new Error("[electro] defineView: name must be a non-empty string");
|
|
60
60
|
if (!VIEW_NAME_PATTERN.test(input.name)) throw new Error(`[electro] defineView: name "${input.name}" is invalid. Must match ${VIEW_NAME_PATTERN.toString()}`);
|
|
61
|
-
if (!input.entry || input.entry.trim().length === 0) throw new Error("[electro] defineView: entry must be a non-empty string");
|
|
62
61
|
return {
|
|
63
62
|
name: input.name,
|
|
64
63
|
entry: input.entry,
|
|
@@ -900,6 +899,55 @@ var ViewManager = class {
|
|
|
900
899
|
}
|
|
901
900
|
};
|
|
902
901
|
|
|
902
|
+
//#endregion
|
|
903
|
+
//#region src/core/view/view.ts
|
|
904
|
+
/**
|
|
905
|
+
* View — manages a single WebContentsView instance.
|
|
906
|
+
*
|
|
907
|
+
* `create()` is idempotent: calling it while an alive view exists returns
|
|
908
|
+
* the existing instance. After the view is destroyed, calling `create()`
|
|
909
|
+
* spawns a fresh one.
|
|
910
|
+
*
|
|
911
|
+
* For renderer-linked views, `load()` resolves the dev URL or production
|
|
912
|
+
* file path automatically.
|
|
913
|
+
*/
|
|
914
|
+
var View = class {
|
|
915
|
+
_view = null;
|
|
916
|
+
constructor(entry) {
|
|
917
|
+
this.entry = entry;
|
|
918
|
+
}
|
|
919
|
+
get id() {
|
|
920
|
+
return this.entry.id;
|
|
921
|
+
}
|
|
922
|
+
create() {
|
|
923
|
+
if (this._view && !this._view.webContents.isDestroyed()) return this._view;
|
|
924
|
+
const { WebContentsView: WCV } = __require("electron");
|
|
925
|
+
const view = new WCV({ webPreferences: { ...this.entry.webPreferences ?? {} } });
|
|
926
|
+
if (this.entry.hasRenderer) {
|
|
927
|
+
const viewId = this.entry.id;
|
|
928
|
+
view.load = async () => {
|
|
929
|
+
const devUrl = process.env[`ELECTRO_DEV_URL_${viewId}`];
|
|
930
|
+
if (devUrl) {
|
|
931
|
+
await view.webContents.loadURL(devUrl);
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
const { app } = await import("electron");
|
|
935
|
+
await view.webContents.loadFile(join(app.getAppPath(), ".electro", "out", "renderer", viewId, "index.html"));
|
|
936
|
+
};
|
|
937
|
+
} else view.load = async () => {};
|
|
938
|
+
this._view = view;
|
|
939
|
+
return view;
|
|
940
|
+
}
|
|
941
|
+
view() {
|
|
942
|
+
if (this._view?.webContents.isDestroyed()) this._view = null;
|
|
943
|
+
return this._view;
|
|
944
|
+
}
|
|
945
|
+
destroy() {
|
|
946
|
+
if (this._view && !this._view.webContents.isDestroyed()) this._view.webContents.close();
|
|
947
|
+
this._view = null;
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
|
|
903
951
|
//#endregion
|
|
904
952
|
//#region src/core/window/manager.ts
|
|
905
953
|
/**
|
|
@@ -952,7 +1000,8 @@ var Runtime = class {
|
|
|
952
1000
|
this.windowManager = new WindowManager();
|
|
953
1001
|
for (const win of config?.windows ?? []) this.windowManager.register(win);
|
|
954
1002
|
this.viewManager = new ViewManager();
|
|
955
|
-
|
|
1003
|
+
const viewRegistry = typeof __ELECTRO_VIEW_REGISTRY__ !== "undefined" ? __ELECTRO_VIEW_REGISTRY__ : [];
|
|
1004
|
+
for (const entry of viewRegistry) this.viewManager.register(new View(entry));
|
|
956
1005
|
this.featureManager.setWindowManager(this.windowManager);
|
|
957
1006
|
this.featureManager.setViewManager(this.viewManager);
|
|
958
1007
|
if (config?.features) this.featureManager.register(config.features);
|
|
@@ -1451,10 +1500,13 @@ function createTask(config) {
|
|
|
1451
1500
|
* `create()` is idempotent: calling it while an alive window exists returns
|
|
1452
1501
|
* the existing instance. After the window is destroyed (user close, etc.),
|
|
1453
1502
|
* calling `create()` again spawns a fresh one.
|
|
1503
|
+
*
|
|
1504
|
+
* API methods from `config.api()` are mixed directly onto the instance
|
|
1505
|
+
* via Object.assign, so callers can do `window.show()` instead of `window.api?.show()`.
|
|
1454
1506
|
*/
|
|
1455
1507
|
var Window = class {
|
|
1456
1508
|
_window = null;
|
|
1457
|
-
|
|
1509
|
+
_apiKeys = null;
|
|
1458
1510
|
constructor(config) {
|
|
1459
1511
|
this.config = config;
|
|
1460
1512
|
}
|
|
@@ -1468,27 +1520,30 @@ var Window = class {
|
|
|
1468
1520
|
show: false,
|
|
1469
1521
|
...this.config.options ?? {}
|
|
1470
1522
|
});
|
|
1471
|
-
if (this.config.api)
|
|
1523
|
+
if (this.config.api) {
|
|
1524
|
+
const api = this.config.api(this._window);
|
|
1525
|
+
this._apiKeys = Object.keys(api);
|
|
1526
|
+
Object.assign(this, api);
|
|
1527
|
+
}
|
|
1472
1528
|
return this._window;
|
|
1473
1529
|
}
|
|
1474
1530
|
get window() {
|
|
1475
1531
|
if (this._window?.isDestroyed()) {
|
|
1476
1532
|
this._window = null;
|
|
1477
|
-
this.
|
|
1533
|
+
this.clearApi();
|
|
1478
1534
|
}
|
|
1479
1535
|
return this._window;
|
|
1480
1536
|
}
|
|
1481
|
-
get api() {
|
|
1482
|
-
if (this._window?.isDestroyed()) {
|
|
1483
|
-
this._window = null;
|
|
1484
|
-
this._api = null;
|
|
1485
|
-
}
|
|
1486
|
-
return this._api;
|
|
1487
|
-
}
|
|
1488
1537
|
destroy() {
|
|
1489
1538
|
if (this._window && !this._window.isDestroyed()) this._window.destroy();
|
|
1490
1539
|
this._window = null;
|
|
1491
|
-
this.
|
|
1540
|
+
this.clearApi();
|
|
1541
|
+
}
|
|
1542
|
+
clearApi() {
|
|
1543
|
+
if (this._apiKeys) {
|
|
1544
|
+
for (const key of this._apiKeys) delete this[key];
|
|
1545
|
+
this._apiKeys = null;
|
|
1546
|
+
}
|
|
1492
1547
|
}
|
|
1493
1548
|
};
|
|
1494
1549
|
|
|
@@ -1506,75 +1561,6 @@ function createWindow(config) {
|
|
|
1506
1561
|
return new Window(config);
|
|
1507
1562
|
}
|
|
1508
1563
|
|
|
1509
|
-
//#endregion
|
|
1510
|
-
//#region src/core/view/view.ts
|
|
1511
|
-
function isRendererConfig(config) {
|
|
1512
|
-
return "renderer" in config;
|
|
1513
|
-
}
|
|
1514
|
-
function resolveRendererName(config) {
|
|
1515
|
-
return config.renderer === true ? config.id : config.renderer;
|
|
1516
|
-
}
|
|
1517
|
-
/**
|
|
1518
|
-
* View — manages a single WebContentsView instance.
|
|
1519
|
-
*
|
|
1520
|
-
* `create()` is idempotent: calling it while an alive view exists returns
|
|
1521
|
-
* the existing instance. After the view is destroyed, calling `create()`
|
|
1522
|
-
* spawns a fresh one.
|
|
1523
|
-
*
|
|
1524
|
-
* For renderer-linked views, `load()` resolves the dev URL or production
|
|
1525
|
-
* file path automatically.
|
|
1526
|
-
*/
|
|
1527
|
-
var View = class {
|
|
1528
|
-
_view = null;
|
|
1529
|
-
constructor(config) {
|
|
1530
|
-
this.config = config;
|
|
1531
|
-
}
|
|
1532
|
-
get id() {
|
|
1533
|
-
return this.config.id;
|
|
1534
|
-
}
|
|
1535
|
-
create() {
|
|
1536
|
-
if (this._view && !this._view.webContents.isDestroyed()) return this._view;
|
|
1537
|
-
const { WebContentsView: WCV } = __require("electron");
|
|
1538
|
-
const view = new WCV({ webPreferences: { ...this.config.webPreferences ?? {} } });
|
|
1539
|
-
if (isRendererConfig(this.config)) {
|
|
1540
|
-
const rendererName = resolveRendererName(this.config);
|
|
1541
|
-
view.load = async () => {
|
|
1542
|
-
const devUrl = process.env[`ELECTRO_DEV_URL_${rendererName}`];
|
|
1543
|
-
if (devUrl) {
|
|
1544
|
-
await view.webContents.loadURL(devUrl);
|
|
1545
|
-
return;
|
|
1546
|
-
}
|
|
1547
|
-
const { app } = await import("electron");
|
|
1548
|
-
await view.webContents.loadFile(join(app.getAppPath(), ".electro", "out", "renderer", rendererName, "index.html"));
|
|
1549
|
-
};
|
|
1550
|
-
} else view.load = async () => {};
|
|
1551
|
-
this._view = view;
|
|
1552
|
-
return view;
|
|
1553
|
-
}
|
|
1554
|
-
view() {
|
|
1555
|
-
if (this._view?.webContents.isDestroyed()) this._view = null;
|
|
1556
|
-
return this._view;
|
|
1557
|
-
}
|
|
1558
|
-
destroy() {
|
|
1559
|
-
if (this._view && !this._view.webContents.isDestroyed()) this._view.webContents.close();
|
|
1560
|
-
this._view = null;
|
|
1561
|
-
}
|
|
1562
|
-
};
|
|
1563
|
-
|
|
1564
|
-
//#endregion
|
|
1565
|
-
//#region src/core/view/helpers.ts
|
|
1566
|
-
/**
|
|
1567
|
-
* Creates a {@link View} instance from a configuration object.
|
|
1568
|
-
*
|
|
1569
|
-
* @param config - View configuration with `id`, and either `renderer` (for Vite-built views) or `webPreferences` (for dynamic views).
|
|
1570
|
-
* @returns A new `View` instance ready for registration.
|
|
1571
|
-
* @throws If `config.id` is empty.
|
|
1572
|
-
*/
|
|
1573
|
-
function createView(config) {
|
|
1574
|
-
if (!config.id) throw new Error("View must have an id");
|
|
1575
|
-
return new View(config);
|
|
1576
|
-
}
|
|
1577
|
-
|
|
1578
1564
|
//#endregion
|
|
1579
1565
|
//#region src/policy/types.ts
|
|
1580
1566
|
/** Outcome of a policy check. */
|
|
@@ -1633,4 +1619,4 @@ var PolicyEngine = class {
|
|
|
1633
1619
|
};
|
|
1634
1620
|
|
|
1635
1621
|
//#endregion
|
|
1636
|
-
export { EventAccessor, FeatureStatus, PolicyDecision, PolicyEngine, Runtime, RuntimeState, ServiceScope, ServiceStatus, TaskOverlapStrategy, TaskRetryStrategy, TaskStatus, createEvent, createFeature, createRuntime, createService, createTask,
|
|
1622
|
+
export { EventAccessor, FeatureStatus, PolicyDecision, PolicyEngine, Runtime, RuntimeState, ServiceScope, ServiceStatus, TaskOverlapStrategy, TaskRetryStrategy, TaskStatus, createEvent, createFeature, createRuntime, createService, createTask, createWindow, defineConfig, defineRuntime, defineView };
|