@mak-98/dirvi-app 0.0.0-stage → 0.11.0-beta.2

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.
Files changed (78) hide show
  1. package/LICENSE +674 -0
  2. package/dist/application/create-dirvi-api.d.ts +10 -0
  3. package/dist/application/create-dirvi-api.d.ts.map +1 -0
  4. package/dist/application/create-dirvi-api.js +23 -0
  5. package/dist/application/init-runtime.d.ts +20 -0
  6. package/dist/application/init-runtime.d.ts.map +1 -0
  7. package/dist/application/init-runtime.js +117 -0
  8. package/dist/application/package-loader.d.ts +9 -0
  9. package/dist/application/package-loader.d.ts.map +1 -0
  10. package/dist/application/package-loader.js +1 -0
  11. package/dist/application/shell-api.d.ts +5 -0
  12. package/dist/application/shell-api.d.ts.map +1 -0
  13. package/dist/application/shell-api.js +1 -0
  14. package/dist/domain/app-pack-ref.d.ts +17 -0
  15. package/dist/domain/app-pack-ref.d.ts.map +1 -0
  16. package/dist/domain/app-pack-ref.js +37 -0
  17. package/dist/domain/app.d.ts +39 -0
  18. package/dist/domain/app.d.ts.map +1 -0
  19. package/dist/domain/app.js +25 -0
  20. package/dist/domain/config.d.ts +402 -0
  21. package/dist/domain/config.d.ts.map +1 -0
  22. package/dist/domain/config.js +44 -0
  23. package/dist/domain/dirvi-api.d.ts +24 -0
  24. package/dist/domain/dirvi-api.d.ts.map +1 -0
  25. package/dist/domain/dirvi-api.js +1 -0
  26. package/dist/domain/ex-command.d.ts +12 -0
  27. package/dist/domain/ex-command.d.ts.map +1 -0
  28. package/dist/domain/ex-command.js +1 -0
  29. package/dist/domain/init-runtime.d.ts +41 -0
  30. package/dist/domain/init-runtime.d.ts.map +1 -0
  31. package/dist/domain/init-runtime.js +1 -0
  32. package/dist/domain/initialization.d.ts +20 -0
  33. package/dist/domain/initialization.d.ts.map +1 -0
  34. package/dist/domain/initialization.js +1 -0
  35. package/dist/domain/public-init-api.d.ts +42 -0
  36. package/dist/domain/public-init-api.d.ts.map +1 -0
  37. package/dist/domain/public-init-api.js +1 -0
  38. package/dist/domain/shell-api.d.ts +5 -0
  39. package/dist/domain/shell-api.d.ts.map +1 -0
  40. package/dist/domain/shell-api.js +1 -0
  41. package/dist/domain/theme.d.ts +536 -0
  42. package/dist/domain/theme.d.ts.map +1 -0
  43. package/dist/domain/theme.js +170 -0
  44. package/dist/domain/view-name-schema.d.ts +18 -0
  45. package/dist/domain/view-name-schema.d.ts.map +1 -0
  46. package/dist/domain/view-name-schema.js +68 -0
  47. package/dist/index.d.ts +17 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +6 -0
  50. package/dist/theme.d.ts +536 -0
  51. package/dist/theme.d.ts.map +1 -0
  52. package/dist/theme.js +170 -0
  53. package/dist/ui/App.d.ts +18 -0
  54. package/dist/ui/App.d.ts.map +1 -0
  55. package/dist/ui/App.js +225 -0
  56. package/dist/ui/AppSetup.d.ts +17 -0
  57. package/dist/ui/AppSetup.d.ts.map +1 -0
  58. package/dist/ui/AppSetup.js +88 -0
  59. package/dist/ui/Shell.d.ts +37 -0
  60. package/dist/ui/Shell.d.ts.map +1 -0
  61. package/dist/ui/Shell.js +52 -0
  62. package/dist/ui/app-screen-renderer.d.ts +28 -0
  63. package/dist/ui/app-screen-renderer.d.ts.map +1 -0
  64. package/dist/ui/app-screen-renderer.js +1 -0
  65. package/dist/ui/color-resolver.d.ts +3 -0
  66. package/dist/ui/color-resolver.d.ts.map +1 -0
  67. package/dist/ui/color-resolver.js +61 -0
  68. package/dist/ui/hooks/useView.d.ts +4 -0
  69. package/dist/ui/hooks/useView.d.ts.map +1 -0
  70. package/dist/ui/hooks/useView.js +32 -0
  71. package/dist/ui/loading-screen-renderer.d.ts +3 -0
  72. package/dist/ui/loading-screen-renderer.d.ts.map +1 -0
  73. package/dist/ui/loading-screen-renderer.js +1 -0
  74. package/dist/ui/view.d.ts +23 -0
  75. package/dist/ui/view.d.ts.map +1 -0
  76. package/dist/ui/view.js +74 -0
  77. package/package.json +34 -3
  78. package/README.md +0 -3
@@ -0,0 +1,10 @@
1
+ import type { DirviApi } from '../domain/dirvi-api.js';
2
+ import type { Initialization } from '../domain/initialization.js';
3
+ /**
4
+ * Creates the runtime application facade from validated initialization data.
5
+ *
6
+ * Registered App values remain private to this module. Consumers interact
7
+ * through app IDs and AppApiApplicator values only.
8
+ */
9
+ export declare function createDirviApi(init: Initialization): DirviApi;
10
+ //# sourceMappingURL=create-dirvi-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-dirvi-api.d.ts","sourceRoot":"","sources":["../../src/application/create-dirvi-api.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,cAAc,GAAG,QAAQ,CAmB7D"}
@@ -0,0 +1,23 @@
1
+ import { createAppApiApplicator, } from '../domain/app.js';
2
+ /**
3
+ * Creates the runtime application facade from validated initialization data.
4
+ *
5
+ * Registered App values remain private to this module. Consumers interact
6
+ * through app IDs and AppApiApplicator values only.
7
+ */
8
+ export function createDirviApi(init) {
9
+ const apps = new Map(init.apps.map((app) => [app.id, app]));
10
+ return {
11
+ config: init.config,
12
+ initialAppId: init.initialAppId,
13
+ appIds: [...apps.keys()],
14
+ customExCommands: init.exCommands,
15
+ openApp: (appId, input) => {
16
+ const app = apps.get(appId);
17
+ if (app === undefined) {
18
+ throw new Error(`App "${appId}" is not registered.`);
19
+ }
20
+ return createAppApiApplicator(app, input);
21
+ },
22
+ };
23
+ }
@@ -0,0 +1,20 @@
1
+ import type { Initialization } from '../domain/initialization.js';
2
+ import type { PublicInitApi } from '../domain/public-init-api.js';
3
+ /**
4
+ * Collects startup configuration registrations while init.mjs is evaluated.
5
+ *
6
+ * The application exposes `api` to the script, then calls `finish()` once
7
+ * evaluation completes to seal registration and obtain the validated Config.
8
+ */
9
+ export type InitRuntime = {
10
+ readonly api: PublicInitApi;
11
+ readonly finish: () => Initialization;
12
+ };
13
+ /**
14
+ * Creates a fresh startup configuration session.
15
+ *
16
+ * Each runtime owns its own mutable configuration while registration is open.
17
+ * The mutable state is not exposed directly to the config script.
18
+ */
19
+ export declare function createInitRuntime(): InitRuntime;
20
+ //# sourceMappingURL=init-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init-runtime.d.ts","sourceRoot":"","sources":["../../src/application/init-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAIlE;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,GAAG,EAAE,aAAa,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,cAAc,CAAC;CACvC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAiI/C"}
@@ -0,0 +1,117 @@
1
+ import { ConfigSchema, defaultConfig, merge } from '../domain/config.js';
2
+ /**
3
+ * Creates a fresh startup configuration session.
4
+ *
5
+ * Each runtime owns its own mutable configuration while registration is open.
6
+ * The mutable state is not exposed directly to the config script.
7
+ */
8
+ export function createInitRuntime() {
9
+ let config = defaultConfig;
10
+ let initialAppId;
11
+ const apps = new Map();
12
+ const exCommands = new Map();
13
+ let finished = false;
14
+ return {
15
+ api: {
16
+ options: {
17
+ set: (patch) => {
18
+ // init.mjs is a startup script. It must not modify startup options
19
+ // after the host has finished evaluating and consuming it.
20
+ if (finished) {
21
+ throw new Error('Initialization has finished. Configure dirvi while init.mjs is being evaluated.');
22
+ }
23
+ // Validate the complete result, not merely the patch. This preserves
24
+ // domain invariants even when a patch changes nested configuration.
25
+ config = ConfigSchema.parse(merge(config, patch));
26
+ },
27
+ },
28
+ apps: {
29
+ register: (id, appReference) => {
30
+ if (finished) {
31
+ throw new Error('Initialization has finished. Register apps while ' +
32
+ 'init.mjs is being evaluated.');
33
+ }
34
+ if (id.trim().length === 0) {
35
+ throw new Error('App ID must not be empty.');
36
+ }
37
+ if (apps.has(id)) {
38
+ throw new Error(`An app with ID "${id}" was registered multiple times.`);
39
+ }
40
+ apps.set(id, appReference);
41
+ },
42
+ initialAppId: (appId) => {
43
+ if (finished) {
44
+ throw new Error('Initialization has finished. Select an initial app while ' +
45
+ 'init.mjs is being evaluated.');
46
+ }
47
+ if (appId.trim().length === 0) {
48
+ throw new Error('App ID must not be empty.');
49
+ }
50
+ initialAppId = appId;
51
+ },
52
+ },
53
+ ex: {
54
+ register: (name, execute) => {
55
+ if (finished) {
56
+ throw new Error('Initialization has finished. Register Ex commands while ' +
57
+ 'init.mjs is being evaluated.');
58
+ }
59
+ if (name.trim().length === 0) {
60
+ throw new Error('Ex command name must not be empty.');
61
+ }
62
+ if (exCommands.has(name)) {
63
+ throw new Error(`An Ex command named "${name}" was registered multiple times.`);
64
+ }
65
+ exCommands.set(name, {
66
+ name,
67
+ execute,
68
+ });
69
+ },
70
+ },
71
+ },
72
+ finish: () => {
73
+ if (finished) {
74
+ throw new Error('Initialization has already finished.');
75
+ }
76
+ if (apps.size === 0) {
77
+ throw new Error('Initialization did not register any apps. Call ' +
78
+ 'dirvi.apps.register(id, appReference) at least once in init.mjs.');
79
+ }
80
+ if (initialAppId !== undefined) {
81
+ if (!apps.has(initialAppId)) {
82
+ throw new Error(`Startup app "${initialAppId}" has not been registered.`);
83
+ }
84
+ finished = true;
85
+ return {
86
+ config,
87
+ initialAppId: initialAppId,
88
+ registeredApps: new Map(apps),
89
+ exCommands: [...exCommands.values()],
90
+ };
91
+ }
92
+ const lastRegisteredAppRef = getLastRegisteredAppId(apps);
93
+ finished = true;
94
+ return {
95
+ config,
96
+ initialAppId: lastRegisteredAppRef,
97
+ registeredApps: new Map(apps),
98
+ exCommands: [...exCommands.values()],
99
+ };
100
+ },
101
+ };
102
+ }
103
+ /**
104
+ * Returns the most recently registered app ID.
105
+ *
106
+ * Map iteration follows registration insertion order. This is a convenience
107
+ * fallback only; init.mjs should set initialAppId explicitly when startup
108
+ * selection is semantically important.
109
+ */
110
+ function getLastRegisteredAppId(apps) {
111
+ const appIds = [...apps.keys()];
112
+ const lastAppId = appIds.at(-1);
113
+ if (lastAppId === undefined) {
114
+ throw new Error('Internal error: Check some app is registered before searching ids.');
115
+ }
116
+ return lastAppId;
117
+ }
@@ -0,0 +1,9 @@
1
+ import type { AppPackageReference } from '../domain/app-pack-ref.js';
2
+ import type { AppPlugin } from 'dirvi-apis';
3
+ /**
4
+ * In the future will be expanded to load other plugins too.
5
+ */
6
+ export type PackageLoader = {
7
+ loadAppPlugin: (reference: AppPackageReference) => Promise<AppPlugin>;
8
+ };
9
+ //# sourceMappingURL=package-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-loader.d.ts","sourceRoot":"","sources":["../../src/application/package-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,aAAa,EAAE,CAAC,SAAS,EAAE,mBAAmB,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;CACvE,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ import type { AppInput } from '../domain/app.js';
2
+ export type ShellApi = {
3
+ readonly openApp: (appId: string, input: AppInput) => Promise<void>;
4
+ };
5
+ //# sourceMappingURL=shell-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-api.d.ts","sourceRoot":"","sources":["../../src/application/shell-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,MAAM,QAAQ,GAAG;IACrB,QAAQ,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ export type NpmAppReference = {
2
+ readonly source: 'npm';
3
+ readonly packageName: string;
4
+ readonly version: string;
5
+ };
6
+ export type AppPackageReference = NpmAppReference;
7
+ /**
8
+ * Parses and validates an app package reference supplied by init.mjs.
9
+ *
10
+ * init.mjs is runtime JavaScript, so TypeScript's AppPackageReference type is
11
+ * not sufficient to establish that a received value is safe to interpret as an
12
+ * npm package reference.
13
+ */
14
+ export declare const AppPackageReference: {
15
+ parse(input: unknown): AppPackageReference;
16
+ };
17
+ //# sourceMappingURL=app-pack-ref.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-pack-ref.d.ts","sourceRoot":"","sources":["../../src/domain/app-pack-ref.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,eAAe,CAAC;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB;iBACjB,OAAO,GAAG,mBAAmB;CA+C3C,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Parses and validates an app package reference supplied by init.mjs.
3
+ *
4
+ * init.mjs is runtime JavaScript, so TypeScript's AppPackageReference type is
5
+ * not sufficient to establish that a received value is safe to interpret as an
6
+ * npm package reference.
7
+ */
8
+ export const AppPackageReference = {
9
+ parse(input) {
10
+ if (!isRecord(input)) {
11
+ throw new Error('Dirvi app package reference must be an object.');
12
+ }
13
+ if (input.source !== 'npm') {
14
+ throw new Error(`Unsupported Dirvi app package source "${String(input.source)}".`);
15
+ }
16
+ if (typeof input.packageName !== 'string') {
17
+ throw new Error('Dirvi npm app package name must be a string.');
18
+ }
19
+ if (!/^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/.test(input.packageName)) {
20
+ throw new Error(`Invalid npm package name "${input.packageName}" for a Dirvi app.`);
21
+ }
22
+ if (typeof input.version !== 'string') {
23
+ throw new Error(`Dirvi app package "${input.packageName}" version must be a string.`);
24
+ }
25
+ if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(input.version)) {
26
+ throw new Error(`Dirvi app package "${input.packageName}" must use an exact version.`);
27
+ }
28
+ return {
29
+ source: 'npm',
30
+ packageName: input.packageName,
31
+ version: input.version,
32
+ };
33
+ },
34
+ };
35
+ function isRecord(value) {
36
+ return typeof value === 'object' && value !== null;
37
+ }
@@ -0,0 +1,39 @@
1
+ import type { AppApiApplicator, AppPlugin } from 'dirvi-apis';
2
+ /**
3
+ * Unique symbol used as computed property name.
4
+ *
5
+ * DO NOT EXPORT: Meant to be private to the file, so `App` has opaque
6
+ * `AppPlugin`.
7
+ */
8
+ declare const appPlugin: unique symbol;
9
+ export type App = {
10
+ /**
11
+ * User-owned identifier from init.mjs.
12
+ *
13
+ * This is intentionally not package-owned plugin metadata. It identifies a
14
+ * configured app instance, so users can register the same plugin more than
15
+ * once under different IDs.
16
+ */
17
+ readonly id: string;
18
+ /**
19
+ * Opaque storage for the plugin implementation.
20
+ *
21
+ * Consumers can inspect the configured app ID, but only this module can
22
+ * obtain and invoke the underlying AppPlugin.
23
+ */
24
+ readonly [appPlugin]: AppPlugin;
25
+ };
26
+ /**
27
+ * Creates one configured app instance from a user-selected ID and a plugin.
28
+ */
29
+ export declare function createApp(id: string, plugin: AppPlugin): App;
30
+ export type AppInput = string | undefined;
31
+ /**
32
+ * Creates the app API applicator for a configured app without exposing the
33
+ * `AppPlugin`.
34
+ *
35
+ * The concrete AppApi generic parameters remain owned by the plugin.
36
+ */
37
+ export declare function createAppApiApplicator(app: App, input: AppInput): AppApiApplicator;
38
+ export {};
39
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/domain/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE9D;;;;;GAKG;AACH,QAAA,MAAM,SAAS,eAAsB,CAAC;AAEtC,MAAM,MAAM,GAAG,GAAG;IAChB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAEpB;;;;;OAKG;IACH,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE,SAAS,CAAC;CACjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,GAAG,CAK5D;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;AAE1C;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,QAAQ,GACd,gBAAgB,CAElB"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Unique symbol used as computed property name.
3
+ *
4
+ * DO NOT EXPORT: Meant to be private to the file, so `App` has opaque
5
+ * `AppPlugin`.
6
+ */
7
+ const appPlugin = Symbol('appPlugin');
8
+ /**
9
+ * Creates one configured app instance from a user-selected ID and a plugin.
10
+ */
11
+ export function createApp(id, plugin) {
12
+ return {
13
+ id,
14
+ [appPlugin]: plugin,
15
+ };
16
+ }
17
+ /**
18
+ * Creates the app API applicator for a configured app without exposing the
19
+ * `AppPlugin`.
20
+ *
21
+ * The concrete AppApi generic parameters remain owned by the plugin.
22
+ */
23
+ export function createAppApiApplicator(app, input) {
24
+ return app[appPlugin].createAppApiApplicator(input);
25
+ }