@rs-x/cli 2.0.0-next.2 → 2.0.0-next.20

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 (66) hide show
  1. package/README.md +5 -0
  2. package/bin/rsx.cjs +1373 -334
  3. package/package.json +5 -1
  4. package/{rs-x-vscode-extension-2.0.0-next.2.vsix → rs-x-vscode-extension-2.0.0-next.20.vsix} +0 -0
  5. package/scripts/prepare-local-rsx-packages.sh +20 -0
  6. package/scripts/verify-rsx-cli-mutations.sh +258 -0
  7. package/scripts/verify-rsx-projects.sh +134 -0
  8. package/scripts/verify-rsx-setup.sh +186 -0
  9. package/templates/angular-demo/README.md +115 -0
  10. package/templates/angular-demo/src/app/app.component.css +97 -0
  11. package/templates/angular-demo/src/app/app.component.html +58 -0
  12. package/templates/angular-demo/src/app/app.component.ts +52 -0
  13. package/templates/angular-demo/src/app/virtual-table/row-data.ts +35 -0
  14. package/templates/angular-demo/src/app/virtual-table/row-model.ts +45 -0
  15. package/templates/angular-demo/src/app/virtual-table/virtual-table-data.service.ts +136 -0
  16. package/templates/angular-demo/src/app/virtual-table/virtual-table-model.ts +224 -0
  17. package/templates/angular-demo/src/app/virtual-table/virtual-table.component.css +174 -0
  18. package/templates/angular-demo/src/app/virtual-table/virtual-table.component.html +50 -0
  19. package/templates/angular-demo/src/app/virtual-table/virtual-table.component.ts +83 -0
  20. package/templates/angular-demo/src/index.html +11 -0
  21. package/templates/angular-demo/src/main.ts +16 -0
  22. package/templates/angular-demo/src/styles.css +261 -0
  23. package/templates/next-demo/README.md +26 -0
  24. package/templates/next-demo/app/globals.css +431 -0
  25. package/templates/next-demo/app/layout.tsx +22 -0
  26. package/templates/next-demo/app/page.tsx +5 -0
  27. package/templates/next-demo/components/demo-app.tsx +114 -0
  28. package/templates/next-demo/components/virtual-table-row.tsx +40 -0
  29. package/templates/next-demo/components/virtual-table-shell.tsx +86 -0
  30. package/templates/next-demo/hooks/use-virtual-table-controller.ts +26 -0
  31. package/templates/next-demo/hooks/use-virtual-table-viewport.ts +41 -0
  32. package/templates/next-demo/lib/row-data.ts +35 -0
  33. package/templates/next-demo/lib/row-model.ts +45 -0
  34. package/templates/next-demo/lib/rsx-bootstrap.ts +46 -0
  35. package/templates/next-demo/lib/virtual-table-controller.ts +259 -0
  36. package/templates/next-demo/lib/virtual-table-data.service.ts +132 -0
  37. package/templates/react-demo/README.md +113 -0
  38. package/templates/react-demo/index.html +12 -0
  39. package/templates/react-demo/src/app/app.tsx +87 -0
  40. package/templates/react-demo/src/app/hooks/use-virtual-table-controller.ts +24 -0
  41. package/templates/react-demo/src/app/hooks/use-virtual-table-viewport.ts +39 -0
  42. package/templates/react-demo/src/app/virtual-table/row-data.ts +35 -0
  43. package/templates/react-demo/src/app/virtual-table/row-model.ts +45 -0
  44. package/templates/react-demo/src/app/virtual-table/virtual-table-controller.ts +259 -0
  45. package/templates/react-demo/src/app/virtual-table/virtual-table-data.service.ts +132 -0
  46. package/templates/react-demo/src/app/virtual-table/virtual-table-row.tsx +38 -0
  47. package/templates/react-demo/src/app/virtual-table/virtual-table-shell.tsx +84 -0
  48. package/templates/react-demo/src/main.tsx +24 -0
  49. package/templates/react-demo/src/rsx-bootstrap.ts +48 -0
  50. package/templates/react-demo/src/styles.css +422 -0
  51. package/templates/react-demo/tsconfig.json +17 -0
  52. package/templates/react-demo/vite.config.ts +6 -0
  53. package/templates/vue-demo/README.md +27 -0
  54. package/templates/vue-demo/src/App.vue +89 -0
  55. package/templates/vue-demo/src/components/VirtualTableRow.vue +33 -0
  56. package/templates/vue-demo/src/components/VirtualTableShell.vue +71 -0
  57. package/templates/vue-demo/src/composables/use-virtual-table-controller.ts +33 -0
  58. package/templates/vue-demo/src/composables/use-virtual-table-viewport.ts +40 -0
  59. package/templates/vue-demo/src/env.d.ts +10 -0
  60. package/templates/vue-demo/src/lib/row-data.ts +35 -0
  61. package/templates/vue-demo/src/lib/row-model.ts +45 -0
  62. package/templates/vue-demo/src/lib/rsx-bootstrap.ts +46 -0
  63. package/templates/vue-demo/src/lib/virtual-table-controller.ts +259 -0
  64. package/templates/vue-demo/src/lib/virtual-table-data.service.ts +132 -0
  65. package/templates/vue-demo/src/main.ts +13 -0
  66. package/templates/vue-demo/src/style.css +440 -0
@@ -0,0 +1,259 @@
1
+ import { type RowData, type SortDirection, type SortKey } from './row-data';
2
+ import { createRowModel, type RowModel, updateRowModel } from './row-model';
3
+ import { VirtualTableDataService } from './virtual-table-data.service';
4
+
5
+ export type RowView = {
6
+ index: number;
7
+ top: number;
8
+ row: RowModel;
9
+ };
10
+
11
+ export type VirtualTableSnapshot = {
12
+ visibleRows: RowView[];
13
+ totalRows: number;
14
+ poolSize: number;
15
+ rowsInView: number;
16
+ loadedPageCount: number;
17
+ spacerHeight: number;
18
+ sortKey: SortKey;
19
+ sortDirection: SortDirection;
20
+ };
21
+
22
+ const ROW_HEIGHT = 36;
23
+ const PAGE_SIZE = 50;
24
+ const POOL_PAGES = 4;
25
+ const CACHE_PADDING_PAGES = 2;
26
+ const RETAIN_PADDING_PAGES = 4;
27
+
28
+ export class VirtualTableController {
29
+ public rowHeight = ROW_HEIGHT;
30
+ public readonly pageSize = PAGE_SIZE;
31
+ public readonly poolSize = PAGE_SIZE * POOL_PAGES;
32
+ public readonly totalRows: number;
33
+
34
+ private scrollTop = 0;
35
+ private viewportHeight = 520;
36
+ private sortKey: SortKey = 'id';
37
+ private sortDirection: SortDirection = 'asc';
38
+ private spacerHeight: number;
39
+ private rowsInView = Math.max(
40
+ 1,
41
+ Math.ceil(this.viewportHeight / this.rowHeight),
42
+ );
43
+ private visibleRows: RowView[] = [];
44
+ private snapshot: VirtualTableSnapshot;
45
+
46
+ private readonly listeners = new Set<() => void>();
47
+ private readonly pool = Array.from({ length: PAGE_SIZE * POOL_PAGES }, () =>
48
+ createRowModel(),
49
+ );
50
+ private readonly dataByIndex = new Map<number, RowData>();
51
+ private readonly loadedPages = new Set<number>();
52
+ private readonly pageLoading = new Map<number, Promise<void>>();
53
+ private readonly dataService = new VirtualTableDataService();
54
+
55
+ public constructor() {
56
+ this.totalRows = this.dataService.totalRows;
57
+ this.spacerHeight = this.totalRows * this.rowHeight;
58
+ this.snapshot = {
59
+ visibleRows: this.visibleRows,
60
+ totalRows: this.totalRows,
61
+ poolSize: this.poolSize,
62
+ rowsInView: this.rowsInView,
63
+ loadedPageCount: this.loadedPages.size,
64
+ spacerHeight: this.spacerHeight,
65
+ sortKey: this.sortKey,
66
+ sortDirection: this.sortDirection,
67
+ };
68
+ this.refresh();
69
+ }
70
+
71
+ public subscribe = (listener: () => void): (() => void) => {
72
+ this.listeners.add(listener);
73
+ return () => {
74
+ this.listeners.delete(listener);
75
+ };
76
+ };
77
+
78
+ public getSnapshot = (): VirtualTableSnapshot => {
79
+ return this.snapshot;
80
+ };
81
+
82
+ public setViewportHeight(height: number): void {
83
+ this.viewportHeight = height;
84
+ this.rowsInView = Math.max(
85
+ 1,
86
+ Math.ceil(this.viewportHeight / this.rowHeight),
87
+ );
88
+ this.refresh();
89
+ }
90
+
91
+ public setRowHeight(height: number): void {
92
+ if (this.rowHeight === height) {
93
+ return;
94
+ }
95
+
96
+ this.rowHeight = height;
97
+ this.spacerHeight = this.totalRows * this.rowHeight;
98
+ this.rowsInView = Math.max(
99
+ 1,
100
+ Math.ceil(this.viewportHeight / this.rowHeight),
101
+ );
102
+ this.refresh();
103
+ }
104
+
105
+ public setScrollTop(value: number): void {
106
+ this.scrollTop = value;
107
+ this.refresh();
108
+ }
109
+
110
+ public toggleSort(nextKey: SortKey): void {
111
+ if (this.sortKey === nextKey) {
112
+ this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
113
+ } else {
114
+ this.sortKey = nextKey;
115
+ this.sortDirection = 'asc';
116
+ }
117
+
118
+ this.resetLoadedData();
119
+ this.refresh();
120
+ }
121
+
122
+ private refresh(): void {
123
+ const scrollIndex = Math.floor(this.scrollTop / this.rowHeight);
124
+ const bufferTop = Math.max(
125
+ 0,
126
+ Math.floor((this.poolSize - this.rowsInView) / 2),
127
+ );
128
+ const maxStart = Math.max(0, this.totalRows - this.poolSize);
129
+ const startIndex = Math.min(Math.max(scrollIndex - bufferTop, 0), maxStart);
130
+ const endIndex = Math.min(startIndex + this.poolSize, this.totalRows);
131
+ const startPage = Math.max(
132
+ 0,
133
+ Math.floor(startIndex / this.pageSize) - CACHE_PADDING_PAGES,
134
+ );
135
+ const endPage = Math.min(
136
+ Math.floor((endIndex - 1) / this.pageSize) + CACHE_PADDING_PAGES,
137
+ Math.floor((this.totalRows - 1) / this.pageSize),
138
+ );
139
+
140
+ this.ensurePages(startPage, endPage);
141
+ this.pruneCachedPages(startPage, endPage);
142
+
143
+ const nextRows: RowView[] = [];
144
+ const length = endIndex - startIndex;
145
+
146
+ for (let offset = 0; offset < length; offset += 1) {
147
+ const index = startIndex + offset;
148
+ const target = this.pool[offset];
149
+ updateRowModel(target, this.getRowData(index));
150
+
151
+ nextRows.push({
152
+ index,
153
+ top: index * this.rowHeight,
154
+ row: target,
155
+ });
156
+ }
157
+
158
+ this.visibleRows = nextRows;
159
+ this.snapshot = {
160
+ visibleRows: this.visibleRows,
161
+ totalRows: this.totalRows,
162
+ poolSize: this.poolSize,
163
+ rowsInView: this.rowsInView,
164
+ loadedPageCount: this.loadedPages.size,
165
+ spacerHeight: this.spacerHeight,
166
+ sortKey: this.sortKey,
167
+ sortDirection: this.sortDirection,
168
+ };
169
+ this.emit();
170
+ }
171
+
172
+ private emit(): void {
173
+ for (const listener of this.listeners) {
174
+ listener();
175
+ }
176
+ }
177
+
178
+ private ensurePages(startPage: number, endPage: number): void {
179
+ for (let pageIndex = startPage; pageIndex <= endPage; pageIndex += 1) {
180
+ this.ensurePageLoaded(pageIndex);
181
+ }
182
+ }
183
+
184
+ private ensurePageLoaded(pageIndex: number): void {
185
+ if (this.loadedPages.has(pageIndex) || this.pageLoading.has(pageIndex)) {
186
+ return;
187
+ }
188
+
189
+ const task = this.loadPageAsync(pageIndex).finally(() => {
190
+ this.pageLoading.delete(pageIndex);
191
+ this.loadedPages.add(pageIndex);
192
+ this.refresh();
193
+ });
194
+
195
+ this.pageLoading.set(pageIndex, task);
196
+ }
197
+
198
+ private async loadPageAsync(pageIndex: number): Promise<void> {
199
+ const page = await this.dataService.fetchPage(
200
+ pageIndex,
201
+ this.pageSize,
202
+ this.sortKey,
203
+ this.sortDirection,
204
+ );
205
+ const startIndex = pageIndex * this.pageSize;
206
+
207
+ for (let offset = 0; offset < page.items.length; offset += 1) {
208
+ const item = page.items[offset];
209
+ if (!item) {
210
+ continue;
211
+ }
212
+
213
+ this.dataByIndex.set(startIndex + offset, item);
214
+ }
215
+ }
216
+
217
+ private getRowData(index: number): RowData {
218
+ const cached = this.dataByIndex.get(index);
219
+ if (cached) {
220
+ return cached;
221
+ }
222
+
223
+ return {
224
+ id: index + 1,
225
+ name: 'Loading...',
226
+ price: 0,
227
+ quantity: 0,
228
+ category: 'Pending',
229
+ updatedAt: '--',
230
+ };
231
+ }
232
+
233
+ private resetLoadedData(): void {
234
+ this.dataByIndex.clear();
235
+ this.loadedPages.clear();
236
+ this.pageLoading.clear();
237
+ }
238
+
239
+ private pruneCachedPages(startPage: number, endPage: number): void {
240
+ const minPage = Math.max(0, startPage - RETAIN_PADDING_PAGES);
241
+ const maxPage = Math.min(
242
+ Math.floor((this.totalRows - 1) / this.pageSize),
243
+ endPage + RETAIN_PADDING_PAGES,
244
+ );
245
+
246
+ for (const pageIndex of Array.from(this.loadedPages)) {
247
+ if (pageIndex >= minPage && pageIndex <= maxPage) {
248
+ continue;
249
+ }
250
+
251
+ this.loadedPages.delete(pageIndex);
252
+ const pageStart = pageIndex * this.pageSize;
253
+ const pageEnd = Math.min(pageStart + this.pageSize, this.totalRows);
254
+ for (let index = pageStart; index < pageEnd; index += 1) {
255
+ this.dataByIndex.delete(index);
256
+ }
257
+ }
258
+ }
259
+ }
@@ -0,0 +1,132 @@
1
+ import {
2
+ createRowData,
3
+ type RowData,
4
+ type SortDirection,
5
+ type SortKey,
6
+ } from './row-data';
7
+
8
+ export type VirtualTablePage = {
9
+ total: number;
10
+ items: RowData[];
11
+ };
12
+
13
+ const TOTAL_ROWS = 1_000_000;
14
+ const REQUEST_DELAY_MS = 120;
15
+ const CATEGORY_COUNT = 4;
16
+ const PRICE_BUCKET_COUNT = 1_000;
17
+ const QUANTITY_BUCKET_COUNT = 100;
18
+ const MAX_CACHED_PAGES = 24;
19
+
20
+ export class VirtualTableDataService {
21
+ private readonly pageCache = new Map<string, VirtualTablePage>();
22
+
23
+ public get totalRows(): number {
24
+ return TOTAL_ROWS;
25
+ }
26
+
27
+ public async fetchPage(
28
+ pageIndex: number,
29
+ pageSize: number,
30
+ sortKey: SortKey,
31
+ sortDirection: SortDirection,
32
+ ): Promise<VirtualTablePage> {
33
+ const cacheKey = `${sortKey}:${sortDirection}:${pageIndex}:${pageSize}`;
34
+ const cached = this.pageCache.get(cacheKey);
35
+ if (cached) {
36
+ return cached;
37
+ }
38
+
39
+ await this.delay(REQUEST_DELAY_MS + (pageIndex % 5) * 35);
40
+
41
+ const startIndex = pageIndex * pageSize;
42
+ const items: RowData[] = [];
43
+ const endIndex = Math.min(startIndex + pageSize, TOTAL_ROWS);
44
+
45
+ for (
46
+ let visualIndex = startIndex;
47
+ visualIndex < endIndex;
48
+ visualIndex += 1
49
+ ) {
50
+ const id = this.getIdAtVisualIndex(visualIndex, sortKey, sortDirection);
51
+ items.push(createRowData(id));
52
+ }
53
+
54
+ const page = { total: TOTAL_ROWS, items };
55
+ this.pageCache.set(cacheKey, page);
56
+ this.trimCache();
57
+ return page;
58
+ }
59
+
60
+ private getIdAtVisualIndex(
61
+ visualIndex: number,
62
+ sortKey: SortKey,
63
+ sortDirection: SortDirection,
64
+ ): number {
65
+ const normalizedIndex =
66
+ sortDirection === 'asc' ? visualIndex : TOTAL_ROWS - 1 - visualIndex;
67
+
68
+ if (sortKey === 'price') {
69
+ return this.getPriceSortedId(normalizedIndex);
70
+ }
71
+
72
+ if (sortKey === 'quantity') {
73
+ return this.getQuantitySortedId(normalizedIndex);
74
+ }
75
+
76
+ if (sortKey === 'category') {
77
+ return this.getCategorySortedId(normalizedIndex);
78
+ }
79
+
80
+ return normalizedIndex + 1;
81
+ }
82
+
83
+ private getPriceSortedId(visualIndex: number): number {
84
+ const groupSize = TOTAL_ROWS / PRICE_BUCKET_COUNT;
85
+ const priceBucket = Math.floor(visualIndex / groupSize);
86
+ const offsetInBucket = visualIndex % groupSize;
87
+
88
+ return priceBucket + offsetInBucket * PRICE_BUCKET_COUNT + 1;
89
+ }
90
+
91
+ private getQuantitySortedId(visualIndex: number): number {
92
+ const groupSize = TOTAL_ROWS / QUANTITY_BUCKET_COUNT;
93
+ const quantityBucket = Math.floor(visualIndex / groupSize);
94
+ const offsetInBucket = visualIndex % groupSize;
95
+ const quantityStride = PRICE_BUCKET_COUNT * QUANTITY_BUCKET_COUNT;
96
+ const quantityBlock = Math.floor(offsetInBucket / PRICE_BUCKET_COUNT);
97
+ const priceBucket = offsetInBucket % PRICE_BUCKET_COUNT;
98
+
99
+ return (
100
+ priceBucket +
101
+ quantityBucket * PRICE_BUCKET_COUNT +
102
+ quantityBlock * quantityStride +
103
+ 1
104
+ );
105
+ }
106
+
107
+ private getCategorySortedId(visualIndex: number): number {
108
+ const groupSize = TOTAL_ROWS / CATEGORY_COUNT;
109
+ const categoryBucket = Math.floor(visualIndex / groupSize);
110
+ const offsetInBucket = visualIndex % groupSize;
111
+
112
+ return categoryBucket + offsetInBucket * CATEGORY_COUNT + 1;
113
+ }
114
+
115
+ private delay(durationMs: number): Promise<void> {
116
+ return new Promise((resolve) => {
117
+ window.setTimeout(resolve, durationMs);
118
+ });
119
+ }
120
+
121
+ private trimCache(): void {
122
+ while (this.pageCache.size > MAX_CACHED_PAGES) {
123
+ const oldestKey = this.pageCache.keys().next().value as
124
+ | string
125
+ | undefined;
126
+ if (!oldestKey) {
127
+ return;
128
+ }
129
+ this.pageCache.delete(oldestKey);
130
+ }
131
+ }
132
+ }
@@ -0,0 +1,38 @@
1
+ import { type FC, memo } from 'react';
2
+
3
+ import { useRsxExpression } from '@rs-x/react';
4
+
5
+ import type { RowView } from './virtual-table-controller';
6
+
7
+ type VirtualTableRowProps = {
8
+ item: RowView;
9
+ };
10
+
11
+ const VirtualTableRowComponent: FC<VirtualTableRowProps> = ({ item }) => {
12
+ const id = useRsxExpression(item.row.idExpr);
13
+ const name = useRsxExpression(item.row.nameExpr);
14
+ const category = useRsxExpression(item.row.categoryExpr);
15
+ const price = useRsxExpression(item.row.priceExpr);
16
+ const quantity = useRsxExpression(item.row.quantityExpr);
17
+ const total = useRsxExpression(item.row.totalExpr);
18
+ const updatedAt = useRsxExpression(item.row.updatedAtExpr);
19
+
20
+ return (
21
+ <div
22
+ className="table-row"
23
+ style={{ transform: `translateY(${item.top}px)` }}
24
+ >
25
+ <span data-label="ID">#{id ?? 0}</span>
26
+ <span data-label="Name">{name ?? ''}</span>
27
+ <span data-label="Category">{category ?? ''}</span>
28
+ <span data-label="Price">€{price ?? 0}</span>
29
+ <span data-label="Qty">{quantity ?? 0}</span>
30
+ <span data-label="Total" className="total">
31
+ €{total ?? 0}
32
+ </span>
33
+ <span data-label="Updated">{updatedAt ?? '--'}</span>
34
+ </div>
35
+ );
36
+ };
37
+
38
+ export const VirtualTableRow = memo(VirtualTableRowComponent);
@@ -0,0 +1,84 @@
1
+ import { type FC } from 'react';
2
+
3
+ import { useVirtualTableController } from '../hooks/use-virtual-table-controller';
4
+ import { useVirtualTableViewport } from '../hooks/use-virtual-table-viewport';
5
+
6
+ import { VirtualTableRow } from './virtual-table-row';
7
+
8
+ export const VirtualTableShell: FC = () => {
9
+ const { controller, snapshot } = useVirtualTableController();
10
+ const viewportRef = useVirtualTableViewport(controller);
11
+
12
+ return (
13
+ <>
14
+ <section className="table-toolbar">
15
+ <div className="toolbar-left">
16
+ <h2>Inventory Snapshot</h2>
17
+ <p>
18
+ {snapshot.totalRows} rows • {snapshot.poolSize} pre-wired models
19
+ </p>
20
+ </div>
21
+ <div className="toolbar-right">
22
+ <button
23
+ type="button"
24
+ onClick={() => {
25
+ controller.toggleSort('price');
26
+ }}
27
+ >
28
+ Sort by price
29
+ </button>
30
+ <button
31
+ type="button"
32
+ onClick={() => {
33
+ controller.toggleSort('quantity');
34
+ }}
35
+ >
36
+ Sort by stock
37
+ </button>
38
+ <button
39
+ type="button"
40
+ onClick={() => {
41
+ controller.toggleSort('name');
42
+ }}
43
+ >
44
+ Sort by name
45
+ </button>
46
+ </div>
47
+ </section>
48
+
49
+ <div className="table-header">
50
+ <span>ID</span>
51
+ <span>Name</span>
52
+ <span>Category</span>
53
+ <span>Price</span>
54
+ <span>Qty</span>
55
+ <span>Total</span>
56
+ <span>Updated</span>
57
+ </div>
58
+
59
+ <div
60
+ ref={viewportRef}
61
+ className="table-viewport"
62
+ onScroll={(event) => {
63
+ controller.setScrollTop(event.currentTarget.scrollTop);
64
+ }}
65
+ >
66
+ <div
67
+ className="table-spacer"
68
+ style={{ height: `${snapshot.spacerHeight}px` }}
69
+ />
70
+ {snapshot.visibleRows.map((item) => (
71
+ <VirtualTableRow key={item.index} item={item} />
72
+ ))}
73
+ </div>
74
+
75
+ <div className="table-footer">
76
+ <div>
77
+ Rows in view: {snapshot.rowsInView} • Loaded pages:{' '}
78
+ {snapshot.loadedPageCount}
79
+ </div>
80
+ <div>Scroll to stream pages from a 1,000,000-row virtual dataset.</div>
81
+ </div>
82
+ </>
83
+ );
84
+ };
@@ -0,0 +1,24 @@
1
+ import { StrictMode } from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+
4
+ import { App } from './app/app';
5
+ import { initRsx } from './rsx-bootstrap';
6
+
7
+ import './styles.css';
8
+
9
+ async function start(): Promise<void> {
10
+ await initRsx();
11
+
12
+ const rootElement = document.getElementById('root');
13
+ if (!rootElement) {
14
+ throw new Error('Missing #root element');
15
+ }
16
+
17
+ createRoot(rootElement).render(
18
+ <StrictMode>
19
+ <App />
20
+ </StrictMode>,
21
+ );
22
+ }
23
+
24
+ void start();
@@ -0,0 +1,48 @@
1
+ import { InjectionContainer } from '@rs-x/core';
2
+ import { RsXExpressionParserModule } from '@rs-x/expression-parser';
3
+
4
+ let initialized = false;
5
+
6
+ type RsxCompiledModule = {
7
+ registerRsxAotCompiledExpressions?: () => void;
8
+ };
9
+
10
+ type RsxPreparsedModule = {
11
+ registerRsxAotParsedExpressionCache?: () => void;
12
+ };
13
+
14
+ async function loadCompiledModule(): Promise<RsxCompiledModule> {
15
+ try {
16
+ return (await import(
17
+ /* @vite-ignore */
18
+ './rsx-generated/' + 'rsx-aot-compiled.generated'
19
+ )) as RsxCompiledModule;
20
+ } catch {
21
+ return {};
22
+ }
23
+ }
24
+
25
+ async function loadPreparsedModule(): Promise<RsxPreparsedModule> {
26
+ try {
27
+ return (await import(
28
+ /* @vite-ignore */
29
+ './rsx-generated/' + 'rsx-aot-preparsed.generated'
30
+ )) as RsxPreparsedModule;
31
+ } catch {
32
+ return {};
33
+ }
34
+ }
35
+
36
+ export async function initRsx(): Promise<void> {
37
+ if (initialized) {
38
+ return;
39
+ }
40
+
41
+ const preparsedModule = await loadPreparsedModule();
42
+ const compiledModule = await loadCompiledModule();
43
+
44
+ preparsedModule.registerRsxAotParsedExpressionCache?.();
45
+ compiledModule.registerRsxAotCompiledExpressions?.();
46
+ await InjectionContainer.load(RsXExpressionParserModule);
47
+ initialized = true;
48
+ }