@adaas/are-html 0.0.23 → 0.0.25
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 +18 -2
- package/dist/browser/index.mjs +35 -10
- package/dist/browser/index.mjs.map +1 -1
- package/dist/node/directives/AreDirectiveIf.directive.d.mts +17 -1
- package/dist/node/directives/AreDirectiveIf.directive.d.ts +17 -1
- 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/engine/AreHTML.compiler.d.mts +3 -1
- package/dist/node/engine/AreHTML.compiler.d.ts +3 -1
- package/dist/node/engine/AreHTML.compiler.js +7 -4
- package/dist/node/engine/AreHTML.compiler.js.map +1 -1
- package/dist/node/engine/AreHTML.compiler.mjs +7 -4
- package/dist/node/engine/AreHTML.compiler.mjs.map +1 -1
- package/examples/for-perf/dist/index.html +1 -1
- package/examples/for-perf/dist/{mqj1mpf2-z4aokv.js → mqp8i2py-vltsx0.js} +2488 -2373
- 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/mqj1mpff-4fr7mw.js → lazy-loading/dist/chunks/chunk-6K72IBO4.js} +2688 -5897
- 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/os-desktop/dist/chunks/chunk-6K72IBO4.js +12455 -0
- 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/{mqiwo23h-bhcolu.js → mqp8hgce-4d6rh0.js} +2911 -2708
- package/package.json +11 -7
- package/src/directives/AreDirectiveIf.directive.ts +33 -4
- package/src/engine/AreHTML.compiler.ts +12 -2
- package/tests/PropPropagation.test.ts +181 -0
- package/tests/jest.setup.ts +11 -0
|
@@ -0,0 +1,121 @@
|
|
|
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 { AppDescriptor, AppRegistry } from "./AppRegistry.fragment";
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* AppComponentResolver — the engine's lazy-loading hook for application code.
|
|
9
|
+
*
|
|
10
|
+
* The engine ({@link AreComponentResolver}) consults this whenever it renders a
|
|
11
|
+
* tag that is NOT a registered component. We answer the question "which app
|
|
12
|
+
* owns this tag, and where do I fetch its class from?".
|
|
13
|
+
*
|
|
14
|
+
* The crucial idea: **an app is ONE bundle that exports a SET of components.**
|
|
15
|
+
* The first time any of an app's tags is requested we dynamically `import()`
|
|
16
|
+
* the app's single bundle (cached per URL), then pick the right named export
|
|
17
|
+
* for the requested tag. The engine registers that class globally, so the next
|
|
18
|
+
* tag from the same app resolves from the already-evaluated module — one
|
|
19
|
+
* network request per app, however many components it ships.
|
|
20
|
+
*
|
|
21
|
+
* Two entry points:
|
|
22
|
+
* - {@link resolve} — the lazy path the engine calls on a render miss.
|
|
23
|
+
* - {@link preload} — the eager path the Launchpad calls on *install*, so
|
|
24
|
+
* "adding an app loads all its components" up front.
|
|
25
|
+
*/
|
|
26
|
+
@A_Frame.Define({
|
|
27
|
+
namespace: 'a-are-os-desktop',
|
|
28
|
+
description: 'Resolves unregistered component tags to classes from their owning app bundle (one code-split bundle per app, many components). Plugged into the engine via AreComponentResolver; also exposes preload() to eagerly load every component of an app on install.'
|
|
29
|
+
})
|
|
30
|
+
export class AppComponentResolver extends AreComponentResolver {
|
|
31
|
+
|
|
32
|
+
protected _registry: AppRegistry;
|
|
33
|
+
|
|
34
|
+
/** Cache of in-flight / settled bundle imports, keyed by bundle URL. */
|
|
35
|
+
protected _bundles: Map<string, Promise<Record<string, unknown>>> = new Map();
|
|
36
|
+
|
|
37
|
+
/** Tags already handed to the engine (registered) — skip re-resolving. */
|
|
38
|
+
protected _resolved: Set<string> = new Set();
|
|
39
|
+
|
|
40
|
+
constructor(data: { registry: AppRegistry }) {
|
|
41
|
+
super({ name: 'AppComponentResolver' });
|
|
42
|
+
this._registry = data.registry;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Lazy path: resolve a single tag on a render miss. Returns `undefined` for
|
|
47
|
+
* tags that do not belong to any installed app (they stay plain elements)
|
|
48
|
+
* or that the engine already has registered.
|
|
49
|
+
*/
|
|
50
|
+
async resolve(entity: string): Promise<A_TYPES__Ctor<Are> | undefined> {
|
|
51
|
+
if (this._resolved.has(entity)) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const app = this._registry.appByComponentTag(entity);
|
|
56
|
+
|
|
57
|
+
if (!app) {
|
|
58
|
+
return undefined;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
const exportName = this.exportNameForTag(app, entity);
|
|
62
|
+
|
|
63
|
+
if (!exportName) {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const mod = await this.importBundle(app.bundle);
|
|
68
|
+
const Component = mod[exportName];
|
|
69
|
+
|
|
70
|
+
if (typeof Component !== 'function') {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
this._resolved.add(entity);
|
|
75
|
+
|
|
76
|
+
return Component as A_TYPES__Ctor<Are>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Eager path: fetch an app's WHOLE bundle (all its components) on install,
|
|
81
|
+
* so "adding an app loads all its necessary components" up front. Called by
|
|
82
|
+
* the Launchpad. It only *warms* the import cache and returns the classes —
|
|
83
|
+
* it deliberately does NOT mark the tags resolved, so the engine still does
|
|
84
|
+
* the actual global registration lazily on first render (now instant,
|
|
85
|
+
* because the bundle is already in memory). This keeps a single owner of
|
|
86
|
+
* registration (the engine) while making install the moment the code lands.
|
|
87
|
+
*/
|
|
88
|
+
async preload(app: AppDescriptor): Promise<A_TYPES__Ctor<Are>[]> {
|
|
89
|
+
const mod = await this.importBundle(app.bundle);
|
|
90
|
+
const classes: A_TYPES__Ctor<Are>[] = [];
|
|
91
|
+
|
|
92
|
+
for (const ref of app.components) {
|
|
93
|
+
const Component = mod[ref.export];
|
|
94
|
+
if (typeof Component === 'function') {
|
|
95
|
+
classes.push(Component as A_TYPES__Ctor<Are>);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return classes;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected exportNameForTag(app: AppDescriptor, tag: string): string | undefined {
|
|
103
|
+
return app.components.find(c => c.tag === tag)?.export;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Dynamic import of an app bundle, de-duplicated per URL. Because the shell
|
|
108
|
+
* and every app bundle are code-split against shared framework chunks, the
|
|
109
|
+
* classes returned here `extend` the SAME `Are`/DI runtime the OS shell runs.
|
|
110
|
+
*/
|
|
111
|
+
protected importBundle(url: string): Promise<Record<string, unknown>> {
|
|
112
|
+
let pending = this._bundles.get(url);
|
|
113
|
+
|
|
114
|
+
if (!pending) {
|
|
115
|
+
pending = import(/* @vite-ignore */ url) as Promise<Record<string, unknown>>;
|
|
116
|
+
this._bundles.set(url, pending);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return pending;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { A_Fragment } from "@adaas/a-concept";
|
|
2
|
+
import { A_Frame } from "@adaas/a-frame/core";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/** A single component contributed by an app's bundle. */
|
|
6
|
+
export type AppComponentRef = {
|
|
7
|
+
/** Custom-element tag (kebab-case of the class name). */
|
|
8
|
+
tag: string;
|
|
9
|
+
/** Named export inside the app bundle that provides this component's class. */
|
|
10
|
+
export: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The public descriptor of an installable application, served by the OS kernel
|
|
15
|
+
* at `GET /api/apps`. It is the single contract between the OS shell and an
|
|
16
|
+
* app: the OS never imports an app's source — it only knows its metadata, the
|
|
17
|
+
* URL of its single code-split bundle, and which tags that bundle provides.
|
|
18
|
+
*/
|
|
19
|
+
export type AppDescriptor = {
|
|
20
|
+
/** Stable id, also the URL segment: `/app/<id>`. */
|
|
21
|
+
id: string;
|
|
22
|
+
/** Human-facing name shown in the dock and window title. */
|
|
23
|
+
name: string;
|
|
24
|
+
/** Emoji used as the app icon. */
|
|
25
|
+
icon: string;
|
|
26
|
+
/** Accent colour for the app's window chrome / dock highlight. */
|
|
27
|
+
accent: string;
|
|
28
|
+
/** Short marketing line shown in the Launchpad. */
|
|
29
|
+
tagline: string;
|
|
30
|
+
/** Root component tag the OS mounts inside the window (e.g. `marketing-app`). */
|
|
31
|
+
rootTag: string;
|
|
32
|
+
/** Public URL of the app's single (code-split) bundle. */
|
|
33
|
+
bundle: string;
|
|
34
|
+
/** Base path of the app's OWN backend API (e.g. `/apps/marketing/api`). */
|
|
35
|
+
api: string;
|
|
36
|
+
/** Every component the bundle exports, so any of its tags can be resolved. */
|
|
37
|
+
components: AppComponentRef[];
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* AppRegistry — the OS's view of the application catalogue.
|
|
43
|
+
*
|
|
44
|
+
* It holds the list of *available* apps (discovered from the backend) and the
|
|
45
|
+
* set the user has *installed*. Installing an app is a frontend-only state
|
|
46
|
+
* change here (the bundle is fetched lazily on demand by the resolver); a real
|
|
47
|
+
* OS would persist this and gate it behind auth/licensing.
|
|
48
|
+
*
|
|
49
|
+
* The registry is a plain data fragment shared across the OS shell components
|
|
50
|
+
* (Dock, Launchpad, MenuBar, AppStage) and the {@link AppComponentResolver}.
|
|
51
|
+
*/
|
|
52
|
+
@A_Frame.Define({
|
|
53
|
+
namespace: 'a-are-os-desktop',
|
|
54
|
+
description: 'Holds the catalogue of available applications (from GET /api/apps) and the set the user has installed. Shared by the OS shell components and the AppComponentResolver to map component tags to their owning app bundle.'
|
|
55
|
+
})
|
|
56
|
+
export class AppRegistry extends A_Fragment {
|
|
57
|
+
|
|
58
|
+
protected _available: AppDescriptor[] = [];
|
|
59
|
+
protected _installed: Set<string> = new Set();
|
|
60
|
+
|
|
61
|
+
constructor(data: { available: AppDescriptor[]; installed?: string[] }) {
|
|
62
|
+
super({ name: 'AppRegistry' });
|
|
63
|
+
this._available = data.available ?? [];
|
|
64
|
+
for (const id of data.installed ?? []) {
|
|
65
|
+
this._installed.add(id);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Every app the backend offers. */
|
|
70
|
+
available(): AppDescriptor[] {
|
|
71
|
+
return this._available;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/** Apps the user has installed, in catalogue order. */
|
|
75
|
+
installed(): AppDescriptor[] {
|
|
76
|
+
return this._available.filter(app => this._installed.has(app.id));
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
isInstalled(id: string): boolean {
|
|
80
|
+
return this._installed.has(id);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
install(id: string): void {
|
|
84
|
+
if (this._available.some(app => app.id === id)) {
|
|
85
|
+
this._installed.add(id);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
uninstall(id: string): void {
|
|
90
|
+
this._installed.delete(id);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Look up an app by its id. */
|
|
94
|
+
get(id: string): AppDescriptor | undefined {
|
|
95
|
+
return this._available.find(app => app.id === id);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/** Find the installed app that owns a given component tag (root or child). */
|
|
99
|
+
appByComponentTag(tag: string): AppDescriptor | undefined {
|
|
100
|
+
return this.installed().find(app =>
|
|
101
|
+
app.rootTag === tag || app.components.some(c => c.tag === tag)
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AreSignal } from "@adaas/are";
|
|
2
|
+
import { A_Frame } from "@adaas/a-frame/core";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* MouseState — the live pointer-position signal.
|
|
7
|
+
*
|
|
8
|
+
* Emitted (throttled) from a global `mousemove` listener wired up in the
|
|
9
|
+
* browser bootstrap. It is a *state* signal, not an event: the bus keeps only
|
|
10
|
+
* the latest value, so any component that mounts later still sees the current
|
|
11
|
+
* pointer position.
|
|
12
|
+
*
|
|
13
|
+
* This example uses it to drive the corner HUD's live coordinates and to prove
|
|
14
|
+
* that several unrelated signal TYPES can travel the same bus and be consumed
|
|
15
|
+
* by `@Are.Signal(MouseState)` typed handlers without interfering with routing.
|
|
16
|
+
*/
|
|
17
|
+
@A_Frame.Define({
|
|
18
|
+
namespace: 'a-are-os-desktop',
|
|
19
|
+
description: 'Live pointer-position state signal {x, y}. Emitted throttled from a global mousemove listener and consumed by the HUD via a typed @Are.Signal(MouseState) handler.'
|
|
20
|
+
})
|
|
21
|
+
export class MouseState extends AreSignal<{ x: number; y: number }> {
|
|
22
|
+
|
|
23
|
+
constructor(x: number, y: number) {
|
|
24
|
+
super({ data: { x, y } });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get x(): number {
|
|
28
|
+
return this.data.x;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get y(): number {
|
|
32
|
+
return this.data.y;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { A_Signal } from "@adaas/a-utils/a-signal";
|
|
2
|
+
import { AreSignal } from "@adaas/are";
|
|
3
|
+
import { A_Frame } from "@adaas/a-frame/core";
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* OSRoute — the routing signal for the OS desktop.
|
|
8
|
+
*
|
|
9
|
+
* The OS uses URL-style routes to decide what the screen shows:
|
|
10
|
+
* - `/` or `/desktop` → empty desktop (wallpaper + dock, no window)
|
|
11
|
+
* - `/launchpad` → the App Store overlay (install apps)
|
|
12
|
+
* - `/app/<id>` → the focused application window for app `<id>`
|
|
13
|
+
*
|
|
14
|
+
* Dispatched by the Dock, the Launchpad and the window chrome. Multiple
|
|
15
|
+
* components react to it independently (the AppStage swaps the visible surface,
|
|
16
|
+
* the MenuBar updates the active-app title, the Dock highlights the running
|
|
17
|
+
* app) — which is the whole point of signal-based routing: one signal, many
|
|
18
|
+
* independent reactions, no shared controller.
|
|
19
|
+
*/
|
|
20
|
+
@A_Frame.Define({
|
|
21
|
+
namespace: 'a-are-os-desktop',
|
|
22
|
+
description: 'OS routing signal carrying the active route (/desktop, /launchpad, /app/<id>). Drives which surface the desktop shows and is consumed independently by the AppStage, MenuBar and Dock.'
|
|
23
|
+
})
|
|
24
|
+
export class OSRoute extends AreSignal<{ path: string }> {
|
|
25
|
+
|
|
26
|
+
constructor(path: string) {
|
|
27
|
+
super({ data: { path } });
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
get path(): string {
|
|
31
|
+
return this.data.path;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
compare(other: A_Signal<{ path: string }>): boolean {
|
|
35
|
+
return this.data.path === other.data.path;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AreSignal } from "@adaas/are";
|
|
2
|
+
import { A_Frame } from "@adaas/a-frame/core";
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* SelectionState — the current text-selection signal.
|
|
7
|
+
*
|
|
8
|
+
* Emitted from a global `selectionchange` listener wired up in the browser
|
|
9
|
+
* bootstrap. Carries the selected text and its length. Like {@link MouseState}
|
|
10
|
+
* it is a *state* signal — the bus retains the latest selection.
|
|
11
|
+
*
|
|
12
|
+
* Two unrelated consumers react to it, demonstrating cross-component reuse of a
|
|
13
|
+
* single signal: the OS HUD shows "N chars selected", and the Marketing app
|
|
14
|
+
* (when open) offers to turn the current selection into a hashtag. Neither
|
|
15
|
+
* consumer knows about the other.
|
|
16
|
+
*/
|
|
17
|
+
@A_Frame.Define({
|
|
18
|
+
namespace: 'a-are-os-desktop',
|
|
19
|
+
description: 'Current text-selection state signal {text, length}. Emitted from a global selectionchange listener and consumed independently by the OS HUD and the Marketing app.'
|
|
20
|
+
})
|
|
21
|
+
export class SelectionState extends AreSignal<{ text: string; length: number }> {
|
|
22
|
+
|
|
23
|
+
constructor(text: string) {
|
|
24
|
+
super({ data: { text, length: text.length } });
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
get text(): string {
|
|
28
|
+
return this.data.text;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get length(): number {
|
|
32
|
+
return this.data.length;
|
|
33
|
+
}
|
|
34
|
+
}
|