@adaas/are-html 0.0.22 → 0.0.24
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/browser/index.d.mts +194 -10
- package/dist/browser/index.mjs +696 -245
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/{AreBinding.attribute-doUvtOjc.d.mts → AreBinding.attribute-BWzEIw6H.d.mts} +45 -0
- package/dist/node/{AreBinding.attribute-Bm5LlOyE.d.ts → AreBinding.attribute-GpT-5Qmf.d.ts} +45 -0
- package/dist/node/attributes/AreBinding.attribute.d.mts +1 -1
- package/dist/node/attributes/AreBinding.attribute.d.ts +1 -1
- package/dist/node/attributes/AreDirective.attribute.d.mts +1 -1
- package/dist/node/attributes/AreDirective.attribute.d.ts +1 -1
- package/dist/node/attributes/AreEvent.attribute.d.mts +1 -1
- package/dist/node/attributes/AreEvent.attribute.d.ts +1 -1
- package/dist/node/attributes/AreStatic.attribute.d.mts +1 -1
- package/dist/node/attributes/AreStatic.attribute.d.ts +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.d.mts +18 -1
- package/dist/node/directives/AreDirectiveFor.directive.d.ts +18 -1
- package/dist/node/directives/AreDirectiveFor.directive.js +57 -9
- package/dist/node/directives/AreDirectiveFor.directive.js.map +1 -1
- package/dist/node/directives/AreDirectiveFor.directive.mjs +57 -9
- package/dist/node/directives/AreDirectiveFor.directive.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveIf.directive.d.mts +18 -2
- package/dist/node/directives/AreDirectiveIf.directive.d.ts +18 -2
- package/dist/node/directives/AreDirectiveIf.directive.js +29 -6
- package/dist/node/directives/AreDirectiveIf.directive.js.map +1 -1
- package/dist/node/directives/AreDirectiveIf.directive.mjs +29 -6
- package/dist/node/directives/AreDirectiveIf.directive.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveShow.directive.d.mts +1 -1
- package/dist/node/directives/AreDirectiveShow.directive.d.ts +1 -1
- package/dist/node/engine/AreHTML.compiler.d.mts +4 -2
- package/dist/node/engine/AreHTML.compiler.d.ts +4 -2
- package/dist/node/engine/AreHTML.compiler.js +11 -4
- package/dist/node/engine/AreHTML.compiler.js.map +1 -1
- package/dist/node/engine/AreHTML.compiler.mjs +11 -4
- package/dist/node/engine/AreHTML.compiler.mjs.map +1 -1
- package/dist/node/engine/AreHTML.constants.d.mts +33 -1
- package/dist/node/engine/AreHTML.constants.d.ts +33 -1
- package/dist/node/engine/AreHTML.constants.js +166 -0
- package/dist/node/engine/AreHTML.constants.js.map +1 -1
- package/dist/node/engine/AreHTML.constants.mjs +165 -1
- package/dist/node/engine/AreHTML.constants.mjs.map +1 -1
- package/dist/node/engine/AreHTML.context.d.mts +66 -0
- package/dist/node/engine/AreHTML.context.d.ts +66 -0
- package/dist/node/engine/AreHTML.context.js +98 -0
- package/dist/node/engine/AreHTML.context.js.map +1 -1
- package/dist/node/engine/AreHTML.context.mjs +98 -0
- package/dist/node/engine/AreHTML.context.mjs.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.d.mts +3 -0
- package/dist/node/engine/AreHTML.interpreter.d.ts +3 -0
- package/dist/node/engine/AreHTML.interpreter.js +66 -10
- package/dist/node/engine/AreHTML.interpreter.js.map +1 -1
- package/dist/node/engine/AreHTML.interpreter.mjs +66 -10
- package/dist/node/engine/AreHTML.interpreter.mjs.map +1 -1
- package/dist/node/engine/AreHTML.lifecycle.d.mts +1 -8
- package/dist/node/engine/AreHTML.lifecycle.d.ts +1 -8
- package/dist/node/engine/AreHTML.lifecycle.js +29 -44
- package/dist/node/engine/AreHTML.lifecycle.js.map +1 -1
- package/dist/node/engine/AreHTML.lifecycle.mjs +29 -44
- package/dist/node/engine/AreHTML.lifecycle.mjs.map +1 -1
- package/dist/node/engine/AreHTML.tokenizer.d.mts +1 -1
- package/dist/node/engine/AreHTML.tokenizer.d.ts +1 -1
- package/dist/node/engine/AreHTML.tokenizer.js +7 -1
- package/dist/node/engine/AreHTML.tokenizer.js.map +1 -1
- package/dist/node/engine/AreHTML.tokenizer.mjs +7 -1
- package/dist/node/engine/AreHTML.tokenizer.mjs.map +1 -1
- package/dist/node/engine/AreHTML.transformer.d.mts +1 -1
- package/dist/node/engine/AreHTML.transformer.d.ts +1 -1
- package/dist/node/index.d.mts +4 -3
- package/dist/node/index.d.ts +4 -3
- package/dist/node/index.js +7 -0
- package/dist/node/index.mjs +1 -0
- package/dist/node/instructions/AddStaticHTML.instruction.d.mts +8 -0
- package/dist/node/instructions/AddStaticHTML.instruction.d.ts +8 -0
- package/dist/node/instructions/AddStaticHTML.instruction.js +31 -0
- package/dist/node/instructions/AddStaticHTML.instruction.js.map +1 -0
- package/dist/node/instructions/AddStaticHTML.instruction.mjs +24 -0
- package/dist/node/instructions/AddStaticHTML.instruction.mjs.map +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.d.mts +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.d.ts +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.js +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.js.map +1 -1
- package/dist/node/instructions/AreHTML.instructions.constants.mjs +1 -0
- package/dist/node/instructions/AreHTML.instructions.constants.mjs.map +1 -1
- package/dist/node/instructions/AreHTML.instructions.types.d.mts +9 -1
- package/dist/node/instructions/AreHTML.instructions.types.d.ts +9 -1
- package/dist/node/lib/AreDirective/AreDirective.component.d.mts +1 -1
- package/dist/node/lib/AreDirective/AreDirective.component.d.ts +1 -1
- package/dist/node/lib/AreDirective/AreDirective.types.d.mts +1 -1
- package/dist/node/lib/AreDirective/AreDirective.types.d.ts +1 -1
- package/dist/node/lib/AreHTML/AreHTML.tokenizer.d.mts +1 -1
- package/dist/node/lib/AreHTML/AreHTML.tokenizer.d.ts +1 -1
- package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.d.mts +1 -1
- package/dist/node/lib/AreHTMLAttribute/AreHTML.attribute.d.ts +1 -1
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.d.mts +1 -1
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.d.ts +1 -1
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.js +51 -0
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.js.map +1 -1
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs +51 -0
- package/dist/node/lib/AreHTMLNode/AreHTMLNode.mjs.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.js.map +1 -1
- package/dist/node/lib/AreRoot/AreRoot.component.mjs.map +1 -1
- package/dist/node/nodes/AreComment.d.mts +1 -1
- package/dist/node/nodes/AreComment.d.ts +1 -1
- package/dist/node/nodes/AreComponent.d.mts +1 -1
- package/dist/node/nodes/AreComponent.d.ts +1 -1
- package/dist/node/nodes/AreInterpolation.d.mts +1 -1
- package/dist/node/nodes/AreInterpolation.d.ts +1 -1
- package/dist/node/nodes/AreRoot.d.mts +1 -1
- package/dist/node/nodes/AreRoot.d.ts +1 -1
- package/dist/node/nodes/AreText.d.mts +1 -1
- package/dist/node/nodes/AreText.d.ts +1 -1
- package/examples/dashboard/concept.ts +1 -1
- package/examples/dashboard/dist/index.html +1 -1
- package/examples/dashboard/dist/{mqh9ryml-xat335.js → mqiw5sqa-ypckmj.js} +403 -57
- package/examples/for-perf/dist/index.html +1 -1
- package/examples/for-perf/dist/{mqh9ryfo-6a8d0o.js → mqp8i2py-vltsx0.js} +3030 -2474
- package/examples/lazy-loading/README.md +76 -0
- package/examples/lazy-loading/concept.ts +55 -0
- package/examples/lazy-loading/containers/UI.container.ts +215 -0
- package/examples/lazy-loading/dist/app.js +3803 -0
- package/examples/{for-perf/dist/mqh9ryfq-4pf5cv.js → lazy-loading/dist/chunks/chunk-6K72IBO4.js} +2708 -5476
- package/examples/lazy-loading/dist/index.html +36 -0
- package/examples/lazy-loading/dist/lazy/about-page.js +59 -0
- package/examples/lazy-loading/dist/lazy/reports-page.js +65 -0
- package/examples/lazy-loading/dist/lazy/settings-page.js +54 -0
- package/examples/lazy-loading/public/index.html +36 -0
- package/examples/lazy-loading/src/components/AppShell.component.ts +44 -0
- package/examples/lazy-loading/src/components/HomePage.component.ts +59 -0
- package/examples/lazy-loading/src/components/LazyOutlet.component.ts +108 -0
- package/examples/lazy-loading/src/components/NavBar.component.ts +98 -0
- package/examples/lazy-loading/src/concept.ts +116 -0
- package/examples/lazy-loading/src/lazy/AboutPage.component.ts +54 -0
- package/examples/lazy-loading/src/lazy/ReportsPage.component.ts +56 -0
- package/examples/lazy-loading/src/lazy/SettingsPage.component.ts +45 -0
- package/examples/lazy-loading/src/runtime/ComponentManifest.fragment.ts +61 -0
- package/examples/lazy-loading/src/runtime/LazyComponentResolver.fragment.ts +77 -0
- package/examples/os-desktop/README.md +91 -0
- package/examples/os-desktop/concept.ts +54 -0
- package/examples/os-desktop/containers/OS.container.ts +198 -0
- package/examples/os-desktop/containers/apps/AppBackend.ts +29 -0
- package/examples/os-desktop/containers/apps/GanttApp.backend.ts +56 -0
- package/examples/os-desktop/containers/apps/MarketingApp.backend.ts +68 -0
- package/examples/os-desktop/dist/app.js +4410 -0
- package/examples/os-desktop/dist/apps/gantt/app.js +271 -0
- package/examples/os-desktop/dist/apps/marketing/app.js +346 -0
- package/examples/{for-perf/dist/mqh9ryde-m243t8.js → os-desktop/dist/chunks/chunk-6K72IBO4.js} +2708 -5476
- package/examples/os-desktop/dist/chunks/chunk-EIIGUL6N.js +30 -0
- package/examples/os-desktop/dist/chunks/chunk-WOH7L5UR.js +30 -0
- package/examples/os-desktop/dist/index.html +33 -0
- package/examples/os-desktop/public/index.html +33 -0
- package/examples/os-desktop/src/apps/gantt/GanttApp.component.ts +41 -0
- package/examples/os-desktop/src/apps/gantt/GanttChart.component.ts +126 -0
- package/examples/os-desktop/src/apps/gantt/GanttStore.ts +47 -0
- package/examples/os-desktop/src/apps/gantt/GanttToolbar.component.ts +73 -0
- package/examples/os-desktop/src/apps/gantt/index.ts +13 -0
- package/examples/os-desktop/src/apps/marketing/MarketingApp.component.ts +53 -0
- package/examples/os-desktop/src/apps/marketing/MarketingStore.ts +34 -0
- package/examples/os-desktop/src/apps/marketing/PostEditor.component.ts +153 -0
- package/examples/os-desktop/src/apps/marketing/PostPreview.component.ts +110 -0
- package/examples/os-desktop/src/apps/marketing/index.ts +16 -0
- package/examples/os-desktop/src/concept.ts +126 -0
- package/examples/os-desktop/src/os/AppStage.component.ts +112 -0
- package/examples/os-desktop/src/os/AppWindow.component.ts +102 -0
- package/examples/os-desktop/src/os/Desktop.component.ts +106 -0
- package/examples/os-desktop/src/os/Dock.component.ts +174 -0
- package/examples/os-desktop/src/os/Hud.component.ts +83 -0
- package/examples/os-desktop/src/os/Launchpad.component.ts +191 -0
- package/examples/os-desktop/src/os/MenuBar.component.ts +156 -0
- package/examples/os-desktop/src/runtime/AppComponentResolver.fragment.ts +121 -0
- package/examples/os-desktop/src/runtime/AppRegistry.fragment.ts +104 -0
- package/examples/os-desktop/src/signals/MouseState.signal.ts +34 -0
- package/examples/os-desktop/src/signals/OSRoute.signal.ts +37 -0
- package/examples/os-desktop/src/signals/SelectionState.signal.ts +34 -0
- package/examples/signal-routing/dist/index.html +1 -1
- package/examples/signal-routing/dist/{mqh9ryc9-dkcbkx.js → mqp8hgce-4d6rh0.js} +3196 -2640
- package/package.json +13 -9
- package/src/directives/AreDirectiveFor.directive.ts +99 -16
- package/src/directives/AreDirectiveIf.directive.ts +33 -4
- package/src/engine/AreHTML.compiler.ts +25 -2
- package/src/engine/AreHTML.constants.ts +142 -0
- package/src/engine/AreHTML.context.ts +112 -0
- package/src/engine/AreHTML.interpreter.ts +114 -13
- package/src/engine/AreHTML.lifecycle.ts +81 -74
- package/src/engine/AreHTML.tokenizer.ts +30 -1
- package/src/index.ts +1 -0
- package/src/instructions/AddStaticHTML.instruction.ts +23 -0
- package/src/instructions/AreHTML.instructions.constants.ts +1 -0
- package/src/instructions/AreHTML.instructions.types.ts +9 -0
- package/src/lib/AreHTMLNode/AreHTMLNode.ts +74 -0
- package/src/lib/AreRoot/AreRoot.component.ts +3 -3
- package/tests/PropPropagation.test.ts +181 -0
- package/tests/StaticIsland.test.ts +115 -0
- package/tests/jest.setup.ts +11 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { A_Concept, A_Context } from "@adaas/a-concept";
|
|
2
|
+
import { A_Config, ConfigReader } from "@adaas/a-utils/a-config";
|
|
3
|
+
import { A_Logger, A_LOGGER_ENV_KEYS } from "@adaas/a-utils/a-logger";
|
|
4
|
+
import { A_SignalBus, A_SignalState } from "@adaas/a-utils/a-signal";
|
|
5
|
+
import { A_Polyfill } from "@adaas/a-utils/a-polyfill";
|
|
6
|
+
import {
|
|
7
|
+
AreContainer,
|
|
8
|
+
AreInit,
|
|
9
|
+
AreSignalsContext,
|
|
10
|
+
} from "@adaas/are";
|
|
11
|
+
import {
|
|
12
|
+
AreRoot,
|
|
13
|
+
AreHTMLEngine,
|
|
14
|
+
AreHTMLEngineContext,
|
|
15
|
+
AreDirectiveIf,
|
|
16
|
+
AreDirectiveFor,
|
|
17
|
+
AreDirectiveShow,
|
|
18
|
+
AreRouteWatcher,
|
|
19
|
+
} from "src";
|
|
20
|
+
|
|
21
|
+
// ── Eager components (shipped in this bundle) ───────────────────────────────
|
|
22
|
+
import { AppShell } from "./components/AppShell.component";
|
|
23
|
+
import { NavBar } from "./components/NavBar.component";
|
|
24
|
+
import { HomePage } from "./components/HomePage.component";
|
|
25
|
+
import { LazyOutlet } from "./components/LazyOutlet.component";
|
|
26
|
+
|
|
27
|
+
// ── Runtime ─────────────────────────────────────────────────────────────────
|
|
28
|
+
import { ComponentManifest, ComponentManifestEntry } from "./runtime/ComponentManifest.fragment";
|
|
29
|
+
import { LazyComponentResolver } from "./runtime/LazyComponentResolver.fragment";
|
|
30
|
+
|
|
31
|
+
// AreRoute must come from are-html (not @adaas/are) so state.has() matches the
|
|
32
|
+
// class NavBar emits — otherwise the bus silently drops every route signal.
|
|
33
|
+
import { AreRoute as AreRouteSignal } from "src/signals/AreRoute.signal";
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
(async () => {
|
|
37
|
+
try {
|
|
38
|
+
// 1. Discover available components from the backend BEFORE bootstrapping.
|
|
39
|
+
// The set of routes/components is server-driven; lazy ones carry a URL
|
|
40
|
+
// the LazyOutlet will dynamically import on first visit.
|
|
41
|
+
const entries: ComponentManifestEntry[] = await fetch('/api/components')
|
|
42
|
+
.then(res => res.json())
|
|
43
|
+
.catch(() => []);
|
|
44
|
+
|
|
45
|
+
const manifest = new ComponentManifest({ entries });
|
|
46
|
+
|
|
47
|
+
// The engine consults this resolver whenever a node's tag does not match
|
|
48
|
+
// a registered component: it imports the lazy bundle from the manifest
|
|
49
|
+
// and the engine registers the returned class globally.
|
|
50
|
+
const componentResolver = new LazyComponentResolver({ manifest });
|
|
51
|
+
|
|
52
|
+
// Empty signals context: the outer <are-root id="app"> has no routing
|
|
53
|
+
// config, so it renders its body (<app-shell>) and ignores route signals.
|
|
54
|
+
// LazyOutlet does its own routing independently.
|
|
55
|
+
const signalsContext = new AreSignalsContext({});
|
|
56
|
+
|
|
57
|
+
const container = new AreContainer({
|
|
58
|
+
name: 'ARE Lazy Loading',
|
|
59
|
+
components: [
|
|
60
|
+
// ── Eager UI ─────────────────────────────────────────────
|
|
61
|
+
AppShell,
|
|
62
|
+
NavBar,
|
|
63
|
+
HomePage,
|
|
64
|
+
LazyOutlet,
|
|
65
|
+
// ── Directives ───────────────────────────────────────────
|
|
66
|
+
AreDirectiveIf,
|
|
67
|
+
AreDirectiveFor,
|
|
68
|
+
AreDirectiveShow,
|
|
69
|
+
// ── Engine ───────────────────────────────────────────────
|
|
70
|
+
A_SignalBus,
|
|
71
|
+
AreRoot,
|
|
72
|
+
AreRouteWatcher,
|
|
73
|
+
ConfigReader,
|
|
74
|
+
AreHTMLEngine,
|
|
75
|
+
A_Logger,
|
|
76
|
+
],
|
|
77
|
+
entities: [
|
|
78
|
+
AreInit,
|
|
79
|
+
AreRouteSignal,
|
|
80
|
+
],
|
|
81
|
+
fragments: [
|
|
82
|
+
// Both AreInit AND AreRouteSignal must be in this state, or
|
|
83
|
+
// state.has() returns false and the bus drops route signals.
|
|
84
|
+
new A_SignalState([AreInit, AreRouteSignal]),
|
|
85
|
+
signalsContext,
|
|
86
|
+
new AreHTMLEngineContext({ container: document }),
|
|
87
|
+
manifest,
|
|
88
|
+
componentResolver,
|
|
89
|
+
new A_Config({
|
|
90
|
+
defaults: {
|
|
91
|
+
[A_LOGGER_ENV_KEYS.LOG_LEVEL]: 'info',
|
|
92
|
+
},
|
|
93
|
+
}),
|
|
94
|
+
],
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const concept = new A_Concept({
|
|
98
|
+
name: 'adaas-are-example-lazy-loading',
|
|
99
|
+
fragments: [
|
|
100
|
+
new A_Config({
|
|
101
|
+
variables: ['CONFIG_VERBOSE', 'DEV_MODE'] as const,
|
|
102
|
+
defaults: { CONFIG_VERBOSE: true, DEV_MODE: true },
|
|
103
|
+
}),
|
|
104
|
+
],
|
|
105
|
+
components: [A_Logger, ConfigReader, A_Polyfill],
|
|
106
|
+
containers: [container],
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
await concept.load();
|
|
110
|
+
await concept.start();
|
|
111
|
+
|
|
112
|
+
} catch (error) {
|
|
113
|
+
const logger = A_Context.root.resolve<A_Logger>(A_Logger)!;
|
|
114
|
+
logger.error(error);
|
|
115
|
+
}
|
|
116
|
+
})();
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { A_Caller, A_Inject } from "@adaas/a-concept";
|
|
2
|
+
import { Are, AreNode } from "@adaas/are";
|
|
3
|
+
import { AreHTMLNode } from "src";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* About page — LAZY. Built into its own bundle (`/lazy/about-page.js`) and NOT
|
|
8
|
+
* registered at bootstrap. It is fetched + registered the first time the
|
|
9
|
+
* `/about` route is visited.
|
|
10
|
+
*
|
|
11
|
+
* Authored exactly like an eager component — the only difference is it lives in
|
|
12
|
+
* `src/lazy/` (its own esbuild entry point) and is `export default`ed so the
|
|
13
|
+
* loader can grab the class without knowing its name.
|
|
14
|
+
*/
|
|
15
|
+
export class AboutPage extends Are {
|
|
16
|
+
|
|
17
|
+
@Are.Template
|
|
18
|
+
template(@A_Inject(A_Caller) node: AreNode) {
|
|
19
|
+
node.setContent(`
|
|
20
|
+
<section class="page">
|
|
21
|
+
<span class="eyebrow">Lazy · fetched on demand</span>
|
|
22
|
+
<h1 class="page-title">About this example</h1>
|
|
23
|
+
<p class="page-lead">
|
|
24
|
+
You just triggered a dynamic <code>import('/lazy/about-page.js')</code>.
|
|
25
|
+
The class was registered into the running scope and rendered into the
|
|
26
|
+
outlet — no page reload, and it wasn't in the initial bundle.
|
|
27
|
+
</p>
|
|
28
|
+
<div class="grid">
|
|
29
|
+
<div class="card"><h3>Code-split</h3><p>The app and every lazy bundle share framework chunks, so this class <code>extends</code> the same <code>Are</code> runtime.</p></div>
|
|
30
|
+
<div class="card"><h3>Backend-driven</h3><p>The server's <code>/api/components</code> manifest decided this page exists and where to fetch it.</p></div>
|
|
31
|
+
<div class="card"><h3>Cached</h3><p>Revisit /about — no second network request. The manifest marks it loaded.</p></div>
|
|
32
|
+
</div>
|
|
33
|
+
</section>
|
|
34
|
+
`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@Are.Styles
|
|
38
|
+
styles(@A_Inject(A_Caller) node: AreHTMLNode) {
|
|
39
|
+
node.setStyles(`
|
|
40
|
+
.page { padding: 48px 56px; max-width: 860px; }
|
|
41
|
+
.eyebrow { display: inline-block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; padding: 4px 10px; border-radius: 999px; margin-bottom: 20px; color: #fcd34d; background: rgba(252, 211, 77, 0.12); }
|
|
42
|
+
.page-title { font-size: 32px; font-weight: 800; color: #f4f4f5; margin-bottom: 14px; letter-spacing: -0.02em; }
|
|
43
|
+
.page-lead { font-size: 16px; color: #a1a1aa; line-height: 1.7; margin-bottom: 28px; }
|
|
44
|
+
code { background: #27272a; padding: 2px 6px; border-radius: 4px; color: #a78bfa; font-size: 13px; }
|
|
45
|
+
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
|
|
46
|
+
.card { background: #1c1c1f; border: 1px solid #27272a; border-radius: 12px; padding: 20px; }
|
|
47
|
+
.card h3 { font-size: 15px; font-weight: 600; color: #f4f4f5; margin-bottom: 8px; }
|
|
48
|
+
.card p { font-size: 13px; color: #71717a; line-height: 1.6; }
|
|
49
|
+
.card code { font-size: 12px; }
|
|
50
|
+
`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export default AboutPage;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { A_Caller, A_Inject } from "@adaas/a-concept";
|
|
2
|
+
import { Are, AreNode } from "@adaas/are";
|
|
3
|
+
import { AreHTMLNode } from "src";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Reports page — LAZY (`/lazy/reports-page.js`). A heavier page (charts/tables)
|
|
8
|
+
* is a classic candidate for code-splitting: there's no reason to pay for it on
|
|
9
|
+
* first paint if most users never open it.
|
|
10
|
+
*/
|
|
11
|
+
export class ReportsPage extends Are {
|
|
12
|
+
|
|
13
|
+
@Are.Template
|
|
14
|
+
template(@A_Inject(A_Caller) node: AreNode) {
|
|
15
|
+
node.setContent(`
|
|
16
|
+
<section class="page">
|
|
17
|
+
<span class="eyebrow">Lazy · fetched on demand</span>
|
|
18
|
+
<h1 class="page-title">Reports</h1>
|
|
19
|
+
<p class="page-lead">Heavy, rarely-visited views are ideal lazy-load candidates — they stay out of the critical path.</p>
|
|
20
|
+
<div class="stats">
|
|
21
|
+
<div class="stat"><div class="stat-value">1,284</div><div class="stat-label">Components served</div></div>
|
|
22
|
+
<div class="stat"><div class="stat-value">96 ms</div><div class="stat-label">Avg load time</div></div>
|
|
23
|
+
<div class="stat"><div class="stat-value">3</div><div class="stat-label">Lazy bundles</div></div>
|
|
24
|
+
<div class="stat"><div class="stat-value">100%</div><div class="stat-label">Cache hit on revisit</div></div>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="bars">
|
|
27
|
+
<div class="bar" style="height: 38%"></div>
|
|
28
|
+
<div class="bar" style="height: 62%"></div>
|
|
29
|
+
<div class="bar" style="height: 48%"></div>
|
|
30
|
+
<div class="bar" style="height: 81%"></div>
|
|
31
|
+
<div class="bar" style="height: 55%"></div>
|
|
32
|
+
<div class="bar" style="height: 72%"></div>
|
|
33
|
+
<div class="bar" style="height: 90%"></div>
|
|
34
|
+
</div>
|
|
35
|
+
</section>
|
|
36
|
+
`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@Are.Styles
|
|
40
|
+
styles(@A_Inject(A_Caller) node: AreHTMLNode) {
|
|
41
|
+
node.setStyles(`
|
|
42
|
+
.page { padding: 48px 56px; max-width: 860px; }
|
|
43
|
+
.eyebrow { display: inline-block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; padding: 4px 10px; border-radius: 999px; margin-bottom: 20px; color: #fcd34d; background: rgba(252, 211, 77, 0.12); }
|
|
44
|
+
.page-title { font-size: 32px; font-weight: 800; color: #f4f4f5; margin-bottom: 14px; letter-spacing: -0.02em; }
|
|
45
|
+
.page-lead { font-size: 16px; color: #a1a1aa; line-height: 1.7; margin-bottom: 28px; }
|
|
46
|
+
.stats { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 16px; margin-bottom: 32px; }
|
|
47
|
+
.stat { background: #1c1c1f; border: 1px solid #27272a; border-radius: 12px; padding: 20px; }
|
|
48
|
+
.stat-value { font-size: 26px; font-weight: 800; color: #a78bfa; }
|
|
49
|
+
.stat-label { font-size: 12px; color: #71717a; margin-top: 6px; }
|
|
50
|
+
.bars { display: flex; align-items: flex-end; gap: 12px; height: 180px; padding: 20px; background: #1c1c1f; border: 1px solid #27272a; border-radius: 12px; }
|
|
51
|
+
.bar { flex: 1; background: linear-gradient(180deg, #a78bfa, #7c3aed); border-radius: 6px 6px 0 0; }
|
|
52
|
+
`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export default ReportsPage;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { A_Caller, A_Inject } from "@adaas/a-concept";
|
|
2
|
+
import { Are, AreNode } from "@adaas/are";
|
|
3
|
+
import { AreHTMLNode } from "src";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Settings page — LAZY (`/lazy/settings-page.js`). Demonstrates that a lazy
|
|
8
|
+
* component can carry its own interactive markup and styles just like any
|
|
9
|
+
* eager one.
|
|
10
|
+
*/
|
|
11
|
+
export class SettingsPage extends Are {
|
|
12
|
+
|
|
13
|
+
@Are.Template
|
|
14
|
+
template(@A_Inject(A_Caller) node: AreNode) {
|
|
15
|
+
node.setContent(`
|
|
16
|
+
<section class="page">
|
|
17
|
+
<span class="eyebrow">Lazy · fetched on demand</span>
|
|
18
|
+
<h1 class="page-title">Settings</h1>
|
|
19
|
+
<p class="page-lead">A second independently-served bundle. It shares the framework runtime with the app via code-split chunks.</p>
|
|
20
|
+
<div class="settings">
|
|
21
|
+
<label class="row"><span>Dark theme</span><input type="checkbox" checked /></label>
|
|
22
|
+
<label class="row"><span>Compact density</span><input type="checkbox" /></label>
|
|
23
|
+
<label class="row"><span>Telemetry</span><input type="checkbox" /></label>
|
|
24
|
+
<label class="row"><span>Auto-update components</span><input type="checkbox" checked /></label>
|
|
25
|
+
</div>
|
|
26
|
+
</section>
|
|
27
|
+
`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@Are.Styles
|
|
31
|
+
styles(@A_Inject(A_Caller) node: AreHTMLNode) {
|
|
32
|
+
node.setStyles(`
|
|
33
|
+
.page { padding: 48px 56px; max-width: 640px; }
|
|
34
|
+
.eyebrow { display: inline-block; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; padding: 4px 10px; border-radius: 999px; margin-bottom: 20px; color: #fcd34d; background: rgba(252, 211, 77, 0.12); }
|
|
35
|
+
.page-title { font-size: 32px; font-weight: 800; color: #f4f4f5; margin-bottom: 14px; letter-spacing: -0.02em; }
|
|
36
|
+
.page-lead { font-size: 16px; color: #a1a1aa; line-height: 1.7; margin-bottom: 28px; }
|
|
37
|
+
.settings { display: flex; flex-direction: column; gap: 2px; border: 1px solid #27272a; border-radius: 12px; overflow: hidden; }
|
|
38
|
+
.row { display: flex; align-items: center; justify-content: space-between; padding: 16px 20px; background: #1c1c1f; font-size: 14px; color: #e4e4e7; }
|
|
39
|
+
.row + .row { border-top: 1px solid #27272a; }
|
|
40
|
+
.row input { width: 18px; height: 18px; accent-color: #a78bfa; }
|
|
41
|
+
`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export default SettingsPage;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { A_Fragment } from "@adaas/a-concept";
|
|
2
|
+
import { A_Frame } from "@adaas/a-frame/core";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
export type ComponentManifestEntry = {
|
|
6
|
+
/** Route that activates this component. */
|
|
7
|
+
route: string;
|
|
8
|
+
/** Custom-element tag (kebab-case of the class name). */
|
|
9
|
+
tag: string;
|
|
10
|
+
/** Class name (PascalCase). */
|
|
11
|
+
name: string;
|
|
12
|
+
/** Public URL to dynamically import (null when bundled eagerly). */
|
|
13
|
+
url: string | null;
|
|
14
|
+
/** Whether the component must be fetched on demand. */
|
|
15
|
+
lazy: boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* App-level fragment that holds the component manifest fetched from the backend
|
|
21
|
+
* (`GET /api/components`) plus a record of which lazy components have already
|
|
22
|
+
* been loaded + registered into the scope.
|
|
23
|
+
*
|
|
24
|
+
* The browser app receives this from the server at bootstrap, so the *set of
|
|
25
|
+
* available components is backend-driven* — the frontend discovers them at
|
|
26
|
+
* runtime rather than hard-coding a component list.
|
|
27
|
+
*/
|
|
28
|
+
@A_Frame.Define({
|
|
29
|
+
namespace: 'a-are-html-example',
|
|
30
|
+
description: 'Holds the backend-served component manifest and tracks which lazy components have been dynamically imported and registered.'
|
|
31
|
+
})
|
|
32
|
+
export class ComponentManifest extends A_Fragment {
|
|
33
|
+
|
|
34
|
+
protected _entries: ComponentManifestEntry[] = [];
|
|
35
|
+
protected _loaded: Set<string> = new Set();
|
|
36
|
+
|
|
37
|
+
constructor(data: { entries: ComponentManifestEntry[] }) {
|
|
38
|
+
super({ name: 'ComponentManifest' });
|
|
39
|
+
this._entries = data.entries ?? [];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** All known components (eager + lazy). */
|
|
43
|
+
list(): ComponentManifestEntry[] {
|
|
44
|
+
return this._entries;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Resolve a route to its component descriptor (exact match). */
|
|
48
|
+
match(route: string): ComponentManifestEntry | undefined {
|
|
49
|
+
return this._entries.find(entry => entry.route === route);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** Has the lazy bundle for this tag already been imported + registered? */
|
|
53
|
+
isLoaded(tag: string): boolean {
|
|
54
|
+
return this._loaded.has(tag);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Mark a lazy component as loaded so we never re-import it. */
|
|
58
|
+
markLoaded(tag: string): void {
|
|
59
|
+
this._loaded.add(tag);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { A_TYPES__Ctor } from "@adaas/a-concept";
|
|
2
|
+
import { A_Frame } from "@adaas/a-frame/core";
|
|
3
|
+
import { Are, AreComponentResolver } from "@adaas/are";
|
|
4
|
+
import { ComponentManifest } from "./ComponentManifest.fragment";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* App-side {@link AreComponentResolver} — the lazy-loading hook the engine
|
|
9
|
+
* consults whenever a node's tag does NOT resolve to a registered component.
|
|
10
|
+
*
|
|
11
|
+
* This is where the "fetch a component from the backend on demand" logic now
|
|
12
|
+
* lives. The engine (AreLoader) calls {@link resolve} with the unresolved tag;
|
|
13
|
+
* if the manifest says that tag is a lazy component, we dynamically `import()`
|
|
14
|
+
* its bundle and hand the class back. The engine then registers that class
|
|
15
|
+
* GLOBALLY (root scope) so every node can resolve it from here on — we no
|
|
16
|
+
* longer touch any scope ourselves.
|
|
17
|
+
*
|
|
18
|
+
* Compared to the previous hand-rolled `LazyOutlet`, the fetch/import/dedupe
|
|
19
|
+
* logic is fully decoupled from rendering: the outlet just sets a `<tag>` and
|
|
20
|
+
* renders; the engine + this resolver handle "where does that class come from".
|
|
21
|
+
*/
|
|
22
|
+
@A_Frame.Define({
|
|
23
|
+
namespace: 'a-are-html-example',
|
|
24
|
+
description: 'Resolves unregistered component tags by dynamically importing their backend-served bundle, per the component manifest. Plugged into the engine via AreComponentResolver; returned classes are registered globally by the engine.'
|
|
25
|
+
})
|
|
26
|
+
export class LazyComponentResolver extends AreComponentResolver {
|
|
27
|
+
|
|
28
|
+
protected _manifest: ComponentManifest;
|
|
29
|
+
|
|
30
|
+
constructor(data: { manifest: ComponentManifest }) {
|
|
31
|
+
super({ name: 'LazyComponentResolver' });
|
|
32
|
+
this._manifest = data.manifest;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Resolve a tag to its component class, fetching the bundle on demand.
|
|
37
|
+
*
|
|
38
|
+
* Returns `undefined` when the tag is not a lazy component in the manifest
|
|
39
|
+
* (eager components are already registered; plain elements stay plain), or
|
|
40
|
+
* when it has already been imported (the engine has it registered, so a
|
|
41
|
+
* second resolve is unnecessary).
|
|
42
|
+
*/
|
|
43
|
+
async resolve(entity: string): Promise<A_TYPES__Ctor<Are> | undefined> {
|
|
44
|
+
const target = this._manifest.list().find(item => item.tag === entity);
|
|
45
|
+
|
|
46
|
+
if (!target || !target.lazy || !target.url || this._manifest.isLoaded(entity)) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const Component = await this.importComponent(target.url);
|
|
51
|
+
|
|
52
|
+
if (!Component) {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this._manifest.markLoaded(entity);
|
|
57
|
+
|
|
58
|
+
return Component as A_TYPES__Ctor<Are>;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Dynamic import of a component bundle served by the backend.
|
|
63
|
+
*
|
|
64
|
+
* Because the app + lazy bundles are code-split against shared framework
|
|
65
|
+
* chunks, the class returned here `extends` the SAME `Are`/DI runtime the
|
|
66
|
+
* host app is running.
|
|
67
|
+
*/
|
|
68
|
+
protected async importComponent(url: string): Promise<Function | undefined> {
|
|
69
|
+
const mod: Record<string, unknown> = await import(/* @vite-ignore */ url);
|
|
70
|
+
|
|
71
|
+
if (typeof mod.default === 'function') {
|
|
72
|
+
return mod.default as Function;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return Object.values(mod).find(value => typeof value === 'function') as Function | undefined;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# ARE · OS Desktop
|
|
2
|
+
|
|
3
|
+
A macOS-style **operating-system desktop** built with ARE, showing how to manage
|
|
4
|
+
**dynamically installable applications** where **each app is its own bundle with
|
|
5
|
+
its own frontend *and* its own backend**, wired together by **signal-based
|
|
6
|
+
routing**.
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
┌──────────────────────────────────────────────── menu bar (OSRoute, Selection)
|
|
10
|
+
│ desktop (wallpaper)
|
|
11
|
+
│ ┌────────────── app window (macOS chrome) ──────────────┐
|
|
12
|
+
│ │ Marketing · post-editor | post-preview │
|
|
13
|
+
│ │ Timeline · gantt-toolbar | gantt-chart │
|
|
14
|
+
│ └───────────────────────────────────────────────────────┘
|
|
15
|
+
│ HUD (MouseState, Selection) dock (OSRoute)
|
|
16
|
+
└──────────────────────────────────────────────────────────────────
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Run
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm run example:os-desktop
|
|
23
|
+
# http://localhost:8084
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The desktop boots empty. Click the dock's **+ (Launchpad)** button, **Install**
|
|
27
|
+
an app — that fetches the app's bundle and adds it to the dock — then open it.
|
|
28
|
+
|
|
29
|
+
## What it demonstrates
|
|
30
|
+
|
|
31
|
+
### 1. Apps are self-contained bundles (FE + BE), installed at runtime
|
|
32
|
+
Each app is a single code-split bundle exporting a **set** of components plus a
|
|
33
|
+
matching backend:
|
|
34
|
+
|
|
35
|
+
| App | Frontend components | Backend endpoint |
|
|
36
|
+
|-------------|----------------------------------------------|-----------------------------------|
|
|
37
|
+
| Marketing | `marketing-app` · `post-editor` · `post-preview` | `GET /apps/marketing/api/hashtags` |
|
|
38
|
+
| Timeline | `gantt-app` · `gantt-toolbar` · `gantt-chart` | `GET /apps/gantt/api/tasks` |
|
|
39
|
+
|
|
40
|
+
The OS kernel (`containers/OS.container.ts`) never imports an app's source. It
|
|
41
|
+
only:
|
|
42
|
+
- advertises descriptors at `GET /api/apps`,
|
|
43
|
+
- builds the shell + every app bundle in **one code-split esbuild pass** (so a
|
|
44
|
+
lazily-`import()`ed app reuses the SAME framework runtime singletons), and
|
|
45
|
+
- routes `/apps/<id>/api/*` to that app's own backend.
|
|
46
|
+
|
|
47
|
+
Adding an app = adding one `AppBackend` to the kernel. Installing it in the UI
|
|
48
|
+
(`AppRegistry.install`) makes it appear in the dock; the
|
|
49
|
+
`AppComponentResolver` then lazily imports its bundle on first render — one
|
|
50
|
+
network request per app, however many components it ships.
|
|
51
|
+
|
|
52
|
+
### 2. Signal-based routing with several signals
|
|
53
|
+
Three OS-wide signals travel on one bus, and many components react to each one
|
|
54
|
+
**independently** — there is no central controller:
|
|
55
|
+
|
|
56
|
+
| Signal | Produced by | Consumed by |
|
|
57
|
+
|------------------|--------------------------------------|-----------------------------------------------|
|
|
58
|
+
| `OSRoute` | dock / launchpad / window chrome | `AppStage` (swaps surface), `MenuBar` (title), `OsDock` (running dot) |
|
|
59
|
+
| `MouseState` | global `mousemove` (throttled) | `OsHud` (x/y read-out), `GanttChart` (guide line) |
|
|
60
|
+
| `SelectionState` | global `selectionchange` | `OsHud` (length), `MenuBar` (chip), `PostPreview` (hashtag hint) |
|
|
61
|
+
|
|
62
|
+
`AppStage` is a custom **signal outlet**: it maps the current `OSRoute` to one
|
|
63
|
+
surface (`app-window` / `os-launchpad` / empty desktop) and swaps it with the
|
|
64
|
+
engine primitives `clear()` + `render()`, unsubscribing the outgoing subtree
|
|
65
|
+
from the bus first.
|
|
66
|
+
|
|
67
|
+
> Every dispatched signal type is listed in BOTH `entities` and the
|
|
68
|
+
> `A_SignalState([...])` structure in `src/concept.ts` — otherwise the bus
|
|
69
|
+
> silently drops it.
|
|
70
|
+
|
|
71
|
+
## Layout
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
os-desktop/
|
|
75
|
+
├── concept.ts # node entry (kernel)
|
|
76
|
+
├── public/index.html # <are-root id="os"><os-desktop>
|
|
77
|
+
├── containers/
|
|
78
|
+
│ ├── OS.container.ts # build + serve + /api/apps + app-API routing
|
|
79
|
+
│ └── apps/
|
|
80
|
+
│ ├── AppBackend.ts # app backend interface
|
|
81
|
+
│ ├── MarketingApp.backend.ts
|
|
82
|
+
│ └── GanttApp.backend.ts
|
|
83
|
+
└── src/
|
|
84
|
+
├── concept.ts # browser bootstrap (registry + resolver + bus)
|
|
85
|
+
├── signals/ # OSRoute · MouseState · SelectionState
|
|
86
|
+
├── runtime/ # AppRegistry + AppComponentResolver
|
|
87
|
+
├── os/ # shell: desktop, menu bar, dock, hud, stage, window, launchpad
|
|
88
|
+
└── apps/
|
|
89
|
+
├── marketing/ # marketing bundle (FE) + own store
|
|
90
|
+
└── gantt/ # gantt bundle (FE) + own store
|
|
91
|
+
```
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { A_Concept, A_Context } from "@adaas/a-concept";
|
|
2
|
+
import { OSContainer } from "./containers/OS.container";
|
|
3
|
+
import { A_Logger } from "@adaas/a-utils/a-logger";
|
|
4
|
+
import { A_Polyfill } from "@adaas/a-utils/a-polyfill";
|
|
5
|
+
import { A_Config, ENVConfigReader } from "@adaas/a-utils/a-config";
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Node-side entry point for the OS Desktop example.
|
|
10
|
+
*
|
|
11
|
+
* The OSContainer is the "kernel": it builds the OS shell bundle plus one
|
|
12
|
+
* code-split bundle per app, serves the static desktop SPA, advertises the
|
|
13
|
+
* installable apps at `/api/apps`, and routes each app's `/apps/<id>/api/*`
|
|
14
|
+
* calls to that app's own backend.
|
|
15
|
+
*
|
|
16
|
+
* In the browser, the desktop boots, you install apps from the Launchpad (each
|
|
17
|
+
* install lazily fetches that app's bundle), open them in macOS-style windows,
|
|
18
|
+
* and watch the OS-wide signals (route / mouse / selection) drive the menu bar,
|
|
19
|
+
* dock and HUD independently.
|
|
20
|
+
*/
|
|
21
|
+
(async () => {
|
|
22
|
+
try {
|
|
23
|
+
const Application = new OSContainer({
|
|
24
|
+
name: 'ARE OS Desktop',
|
|
25
|
+
components: [
|
|
26
|
+
A_Polyfill,
|
|
27
|
+
ENVConfigReader,
|
|
28
|
+
A_Logger,
|
|
29
|
+
],
|
|
30
|
+
fragments: [
|
|
31
|
+
new A_Config({
|
|
32
|
+
defaults: {
|
|
33
|
+
PORT: 8084,
|
|
34
|
+
CONFIG_VERBOSE: true,
|
|
35
|
+
DEV_MODE: true,
|
|
36
|
+
}
|
|
37
|
+
}),
|
|
38
|
+
]
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const concept = new A_Concept({
|
|
42
|
+
name: 'adaas-are-example-os-desktop',
|
|
43
|
+
components: [A_Logger, A_Polyfill, ENVConfigReader],
|
|
44
|
+
containers: [Application],
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
await concept.load();
|
|
48
|
+
await concept.start();
|
|
49
|
+
|
|
50
|
+
} catch (error) {
|
|
51
|
+
const logger = A_Context.root.resolve<A_Logger>(A_Logger)!;
|
|
52
|
+
logger.error(error);
|
|
53
|
+
}
|
|
54
|
+
})();
|