slicejs-web-framework 3.4.4 → 3.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/Slice/Components/Structural/Controller/Controller.js +135 -0
  2. package/Slice/Components/Structural/EventManager/EventManager.js +289 -4
  3. package/Slice/Components/Structural/EventManager/EventManagerDebugger.js +368 -30
  4. package/Slice/Components/Structural/LeakInspector/LeakInspector.js +296 -0
  5. package/Slice/Slice.js +14 -1
  6. package/Slice/tests/event-emitters.test.js +79 -0
  7. package/Slice/tests/event-registry.test.js +141 -0
  8. package/Slice/tests/leak-orphans.test.js +131 -0
  9. package/api/index.js +35 -8
  10. package/package.json +1 -1
  11. package/sliceConfig.schema.json +10 -1
  12. package/src/sliceConfig.json +5 -1
  13. package/types/index.d.ts +12 -0
  14. package/slicejs-cli/.github/workflows/ci.yml +0 -43
  15. package/slicejs-cli/LICENSE +0 -21
  16. package/slicejs-cli/assets/Slice.js-logo.png +0 -0
  17. package/slicejs-cli/client.js +0 -740
  18. package/slicejs-cli/commands/Print.js +0 -164
  19. package/slicejs-cli/commands/Validations.js +0 -92
  20. package/slicejs-cli/commands/build/build.js +0 -40
  21. package/slicejs-cli/commands/buildProduction/buildProduction.js +0 -577
  22. package/slicejs-cli/commands/bundle/bundle.js +0 -236
  23. package/slicejs-cli/commands/createComponent/VisualComponentTemplate.js +0 -55
  24. package/slicejs-cli/commands/createComponent/createComponent.js +0 -128
  25. package/slicejs-cli/commands/deleteComponent/deleteComponent.js +0 -81
  26. package/slicejs-cli/commands/doctor/doctor.js +0 -516
  27. package/slicejs-cli/commands/getComponent/getComponent.js +0 -695
  28. package/slicejs-cli/commands/init/init.js +0 -473
  29. package/slicejs-cli/commands/listComponents/listComponents.js +0 -172
  30. package/slicejs-cli/commands/startServer/startServer.js +0 -240
  31. package/slicejs-cli/commands/startServer/watchServer.js +0 -66
  32. package/slicejs-cli/commands/types/types.js +0 -583
  33. package/slicejs-cli/commands/utils/LocalCliDelegation.js +0 -53
  34. package/slicejs-cli/commands/utils/PackageManager.js +0 -148
  35. package/slicejs-cli/commands/utils/PathHelper.js +0 -75
  36. package/slicejs-cli/commands/utils/VersionChecker.js +0 -169
  37. package/slicejs-cli/commands/utils/bundling/BundleGenerator.js +0 -2525
  38. package/slicejs-cli/commands/utils/bundling/DependencyAnalyzer.js +0 -933
  39. package/slicejs-cli/commands/utils/loadConfig.js +0 -31
  40. package/slicejs-cli/commands/utils/sliceScripts.js +0 -48
  41. package/slicejs-cli/commands/utils/updateManager.js +0 -471
  42. package/slicejs-cli/package.json +0 -71
  43. package/slicejs-cli/playwright.config.js +0 -51
  44. package/slicejs-cli/pnpm-lock.yaml +0 -1629
  45. package/slicejs-cli/tests/build-command-integration.test.js +0 -87
  46. package/slicejs-cli/tests/build-mangling-e2e.test.js +0 -290
  47. package/slicejs-cli/tests/build-production-e2e.test.js +0 -140
  48. package/slicejs-cli/tests/builder-edge-cases.test.js +0 -322
  49. package/slicejs-cli/tests/bundle-generate-e2e.test.js +0 -115
  50. package/slicejs-cli/tests/bundle-generator.test.js +0 -691
  51. package/slicejs-cli/tests/bundle-v2-register-output.test.js +0 -470
  52. package/slicejs-cli/tests/bundling-dependency-edges.test.js +0 -127
  53. package/slicejs-cli/tests/bundling-imports-unit.test.js +0 -267
  54. package/slicejs-cli/tests/client-launcher-contract.test.js +0 -211
  55. package/slicejs-cli/tests/commands-component-crud.test.js +0 -128
  56. package/slicejs-cli/tests/commands-doctor.test.js +0 -152
  57. package/slicejs-cli/tests/commands-version-checker.test.js +0 -37
  58. package/slicejs-cli/tests/component-registry-parse.test.js +0 -34
  59. package/slicejs-cli/tests/dependency-analyzer.test.js +0 -24
  60. package/slicejs-cli/tests/e2e/bundles.spec.js +0 -91
  61. package/slicejs-cli/tests/e2e/dependency-scenarios.spec.js +0 -56
  62. package/slicejs-cli/tests/e2e/fixtures/components/Service/FetchManager/FetchManager.js +0 -136
  63. package/slicejs-cli/tests/e2e/fixtures/components/Service/IndexedDbManager/IndexedDbManager.js +0 -149
  64. package/slicejs-cli/tests/e2e/fixtures/components/Service/LocalStorageManager/LocalStorageManager.js +0 -45
  65. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.css +0 -106
  66. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.html +0 -5
  67. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Button/Button.js +0 -158
  68. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Link/Link.js +0 -33
  69. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.css +0 -56
  70. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.html +0 -83
  71. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Loading/Loading.js +0 -164
  72. package/slicejs-cli/tests/e2e/fixtures/components/Visual/MultiRoute/MultiRoute.js +0 -167
  73. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.css +0 -116
  74. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.html +0 -44
  75. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Navbar/Navbar.js +0 -180
  76. package/slicejs-cli/tests/e2e/fixtures/components/Visual/NotFound/NotFound.js +0 -20
  77. package/slicejs-cli/tests/e2e/fixtures/components/Visual/Route/Route.js +0 -181
  78. package/slicejs-cli/tests/e2e/fixtures/components/registry.json +0 -12
  79. package/slicejs-cli/tests/e2e/fixtures/vendor-components.mjs +0 -65
  80. package/slicejs-cli/tests/e2e/navigation.spec.js +0 -44
  81. package/slicejs-cli/tests/e2e/render.spec.js +0 -34
  82. package/slicejs-cli/tests/e2e/serve.mjs +0 -264
  83. package/slicejs-cli/tests/e2e/shared-deps.spec.js +0 -61
  84. package/slicejs-cli/tests/e2e/unminified.spec.js +0 -33
  85. package/slicejs-cli/tests/e2e-serve.test.js +0 -148
  86. package/slicejs-cli/tests/fixtures/components.js +0 -8
  87. package/slicejs-cli/tests/fixtures/sliceConfig.json +0 -74
  88. package/slicejs-cli/tests/getcomponent.test.js +0 -435
  89. package/slicejs-cli/tests/helpers/setup.js +0 -102
  90. package/slicejs-cli/tests/init-command-contract.test.js +0 -101
  91. package/slicejs-cli/tests/init-e2e.test.js +0 -82
  92. package/slicejs-cli/tests/init-project-isolation.test.js +0 -98
  93. package/slicejs-cli/tests/local-cli-delegation.test.js +0 -81
  94. package/slicejs-cli/tests/package-manager.test.js +0 -127
  95. package/slicejs-cli/tests/path-helper.test.js +0 -206
  96. package/slicejs-cli/tests/perf-budget.test.js +0 -84
  97. package/slicejs-cli/tests/postinstall-command.test.js +0 -103
  98. package/slicejs-cli/tests/property-mangling-regression.test.js +0 -182
  99. package/slicejs-cli/tests/types-breakage.test.js +0 -491
  100. package/slicejs-cli/tests/types-generator-errors.test.js +0 -361
  101. package/slicejs-cli/tests/types-generator.test.js +0 -348
@@ -1,348 +0,0 @@
1
- import { test } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import fs from 'node:fs';
4
- import path from 'node:path';
5
- import { createTestProject, cleanupTestProject } from './helpers/setup.js';
6
-
7
- import {
8
- ensureEditorConfigForTypes,
9
- ensureNoCheckInPublicVendorFiles,
10
- extractStaticPropsFromSource,
11
- generateDeclarationContent,
12
- generateTypesFile
13
- } from '../commands/types/types.js';
14
-
15
- test('extractStaticPropsFromSource reads static props definitions', () => {
16
- const source = `
17
- export default class Button extends HTMLElement {
18
- static props = {
19
- value: { type: 'string', default: 'Button', allowedValues: ['Button', 'Submit'] },
20
- disabled: { type: 'boolean', default: false },
21
- size: { type: 'number', allowedValues: [12, 16, 20] },
22
- options: {
23
- type: 'object',
24
- schema: {
25
- theme: {
26
- type: 'object',
27
- schema: {
28
- mode: { type: 'string', allowedValues: ['light', 'dark'] }
29
- }
30
- }
31
- }
32
- },
33
- steps: {
34
- type: 'array',
35
- items: {
36
- type: 'object',
37
- schema: {
38
- id: { type: 'string', required: true },
39
- enabled: { type: 'boolean', default: true }
40
- }
41
- }
42
- },
43
- onClickCallback: { type: 'function', required: true }
44
- };
45
- }
46
- `;
47
-
48
- const result = extractStaticPropsFromSource(source);
49
-
50
- assert.deepEqual(result, {
51
- value: { type: 'string', required: false, allowedValues: ['Button', 'Submit'] },
52
- disabled: { type: 'boolean', required: false },
53
- size: { type: 'number', required: false, allowedValues: [12, 16, 20] },
54
- options: {
55
- type: 'object',
56
- required: false,
57
- schema: {
58
- theme: {
59
- type: 'object',
60
- required: false,
61
- schema: {
62
- mode: {
63
- type: 'string',
64
- required: false,
65
- allowedValues: ['light', 'dark']
66
- }
67
- }
68
- }
69
- }
70
- },
71
- steps: {
72
- type: 'array',
73
- required: false,
74
- items: {
75
- type: 'object',
76
- required: false,
77
- schema: {
78
- id: { type: 'string', required: true },
79
- enabled: { type: 'boolean', required: false }
80
- }
81
- }
82
- },
83
- onClickCallback: { type: 'function', required: true }
84
- });
85
- });
86
-
87
- test('generateDeclarationContent creates build typing map', () => {
88
- const content = generateDeclarationContent({
89
- Button: {
90
- value: { type: 'string', required: false, allowedValues: ['primary', 'secondary', 'danger'] },
91
- size: { type: 'number', required: false, allowedValues: [12, 16] },
92
- disabled: { type: 'boolean', required: false },
93
- status: { type: 'string', required: false, allowedValues: ['ok', 1] },
94
- options: {
95
- type: 'object',
96
- required: false,
97
- schema: {
98
- mode: { type: 'string', required: false, allowedValues: ['light', 'dark'] }
99
- }
100
- },
101
- steps: {
102
- type: 'array',
103
- required: false,
104
- items: {
105
- type: 'object',
106
- required: false,
107
- schema: {
108
- id: { type: 'string', required: true }
109
- }
110
- }
111
- }
112
- },
113
- FetchManager: {
114
- baseUrl: { type: 'string', required: true }
115
- }
116
- });
117
-
118
- assert.match(content, /export interface ButtonProps/);
119
- assert.match(content, /\[key: string\]: unknown;/);
120
- assert.match(content, /value\?: 'primary' \| 'secondary' \| 'danger';/);
121
- assert.match(content, /size\?: 12 \| 16;/);
122
- assert.match(content, /disabled\?: boolean;/);
123
- assert.match(content, /status\?: string;/);
124
- assert.match(content, /export interface FetchManagerProps/);
125
- assert.match(content, /baseUrl: string;/);
126
- assert.match(content, /export interface SliceComponentPropsMap/);
127
- assert.match(content, /Button: ButtonProps;/);
128
- assert.match(content, /FetchManager: FetchManagerProps;/);
129
- assert.match(content, /options\?: \{/);
130
- assert.match(content, /mode\?: 'light' \| 'dark';/);
131
- assert.match(content, /steps\?: \{/);
132
- assert.match(content, /id: string;/);
133
- assert.match(content, /}\[\];/);
134
- assert.match(content, /declare module 'slicejs-web-framework'/);
135
- assert.match(content, /interface SliceApi \{/);
136
- assert.match(content, /export type SliceDynamicElement = HTMLElement & Record<string, any>;/);
137
- assert.match(content, /build<K extends SliceComponentName>/);
138
- assert.match(content, /getComponent<K extends SliceComponentName>\(/);
139
- assert.match(content, /componentSliceId: K \|/);
140
- assert.match(content, /SliceDynamicElement \| undefined;/);
141
- assert.match(content, /getComponent<T extends SliceDynamicElement = SliceDynamicElement>\(/);
142
- assert.match(content, /\): T \| undefined;/);
143
- assert.match(content, /interface Element \{/);
144
- assert.match(content, /querySelector<E extends Element = HTMLElement>\(selectors: string\): E \| null;/);
145
- assert.match(content, /querySelectorAll<E extends Element = HTMLElement>\(selectors: string\): NodeListOf<E>;/);
146
- assert.match(content, /interface HTMLElement \{/);
147
- assert.match(content, /\[key: string\]: any;/);
148
- assert.match(content, /const slice: SliceBuildApi & Record<string, any>;/);
149
- assert.match(content, /interface EventTarget \{/);
150
- assert.match(content, /interface Event \{/);
151
- assert.match(content, /detail: any;/);
152
- assert.match(content, /currentTarget: any;/);
153
- });
154
-
155
- test('generateTypesFile creates declaration file from local components', async () => {
156
- const tmpRoot = await createTestProject();
157
- const srcDir = path.join(tmpRoot, 'src');
158
-
159
- try {
160
- const visualDir = path.join(srcDir, 'Components', 'Visual', 'Button');
161
- const noStaticDir = path.join(srcDir, 'Components', 'Visual', 'Tabs');
162
- const serviceDir = path.join(srcDir, 'Components', 'Service', 'FetchManager');
163
- const outputFile = path.join(srcDir, 'slice-build.generated.d.ts');
164
-
165
- fs.mkdirSync(visualDir, { recursive: true });
166
- fs.mkdirSync(noStaticDir, { recursive: true });
167
- fs.mkdirSync(serviceDir, { recursive: true });
168
-
169
- fs.writeFileSync(
170
- path.join(visualDir, 'Button.js'),
171
- `
172
- export default class Button extends HTMLElement {
173
- static props = {
174
- value: { type: 'string', default: 'Button', allowedValues: ['Button', 'Submit'] },
175
- size: { type: 'number', allowedValues: [12, 16] },
176
- disabled: { type: 'boolean', default: false }
177
- };
178
- }
179
- `,
180
- 'utf8'
181
- );
182
-
183
- fs.writeFileSync(
184
- path.join(noStaticDir, 'Tabs.js'),
185
- `
186
- export default class Tabs extends HTMLElement {
187
- constructor() {
188
- super();
189
- }
190
- }
191
- `,
192
- 'utf8'
193
- );
194
-
195
- fs.writeFileSync(
196
- path.join(serviceDir, 'FetchManager.js'),
197
- `
198
- export default class FetchManager extends HTMLElement {
199
- static props = {
200
- baseUrl: { type: 'string', required: true }
201
- };
202
- }
203
- `,
204
- 'utf8'
205
- );
206
-
207
- fs.writeFileSync(
208
- path.join(srcDir, 'Components', 'components.js'),
209
- 'const components = {"Button": "Visual", "Tabs": "Visual", "FetchManager": "Service"};\n\nexport default components;\n',
210
- 'utf8'
211
- );
212
-
213
- const result = await generateTypesFile({
214
- projectRoot: tmpRoot,
215
- outputPath: outputFile
216
- });
217
-
218
- assert.equal(result.componentsProcessed, 3);
219
- assert.equal(fs.existsSync(result.outputPath), true);
220
-
221
- const declaration = fs.readFileSync(result.outputPath, 'utf8');
222
- assert.match(declaration, /export interface ButtonProps/);
223
- assert.match(declaration, /value\?: 'Button' \| 'Submit';/);
224
- assert.match(declaration, /size\?: 12 \| 16;/);
225
- assert.match(declaration, /export interface TabsProps/);
226
- assert.match(declaration, /\[key: string\]: unknown;/);
227
- assert.match(declaration, /export interface FetchManagerProps/);
228
- assert.match(declaration, /Tabs: TabsProps;/);
229
- assert.match(declaration, /build<K extends SliceComponentName>/);
230
- } finally {
231
- await cleanupTestProject(tmpRoot);
232
- }
233
- });
234
-
235
- test('ensureEditorConfigForTypes creates jsconfig when missing', async () => {
236
- const tmpRoot = await createTestProject();
237
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
238
-
239
- try {
240
- fs.writeFileSync(outputFile, 'export {};\n', 'utf8');
241
-
242
- const result = await ensureEditorConfigForTypes({
243
- projectRoot: tmpRoot,
244
- outputPath: outputFile
245
- });
246
-
247
- assert.equal(result.mode, 'created_jsconfig');
248
-
249
- const jsconfigPath = path.join(tmpRoot, 'jsconfig.json');
250
- assert.equal(fs.existsSync(jsconfigPath), true);
251
-
252
- const jsconfig = JSON.parse(fs.readFileSync(jsconfigPath, 'utf8'));
253
- assert.equal(Array.isArray(jsconfig.include), true);
254
- assert.equal(jsconfig.include.includes('src/Components/**/*.js'), true);
255
- assert.equal(jsconfig.include.includes('src/**/*.d.ts'), true);
256
- assert.equal(jsconfig.include.includes('api/**/*.js'), false);
257
- assert.equal(jsconfig.include.includes('tests/**/*.js'), false);
258
- assert.equal(jsconfig.include.includes('src/**/*.js'), false);
259
- assert.equal(jsconfig.compilerOptions.checkJs, true);
260
- assert.equal(jsconfig.compilerOptions.strictNullChecks, false);
261
- assert.equal(jsconfig.compilerOptions.noImplicitAny, false);
262
- assert.equal(jsconfig.compilerOptions.strict, false);
263
- assert.equal(Array.isArray(jsconfig.exclude), true);
264
- assert.equal(jsconfig.exclude.includes('src/libs/**'), true);
265
- assert.equal(jsconfig.exclude.includes('tests/**'), true);
266
- } finally {
267
- await cleanupTestProject(tmpRoot);
268
- }
269
- });
270
-
271
- test('types functions use PathHelper with explicit projectRoot', async () => {
272
- const tmpRoot = await createTestProject({ visualComponents: ['Button'] });
273
- const srcDir = path.join(tmpRoot, 'src');
274
- const outputFile = path.join(srcDir, 'slice-build.generated.d.ts');
275
-
276
- try {
277
- const visualDir = path.join(srcDir, 'Components', 'Visual', 'Button');
278
- fs.writeFileSync(
279
- path.join(visualDir, 'Button.js'),
280
- `export default class Button extends HTMLElement {
281
- static props = { value: { type: 'string' } };
282
- }`,
283
- 'utf8'
284
- );
285
-
286
- const result = await generateTypesFile({
287
- projectRoot: tmpRoot,
288
- outputPath: outputFile
289
- });
290
-
291
- assert.equal(result.componentsProcessed, 1);
292
- assert.equal(fs.existsSync(result.outputPath), true);
293
-
294
- const declaration = fs.readFileSync(result.outputPath, 'utf8');
295
- assert.match(declaration, /export interface ButtonProps/);
296
- assert.match(declaration, /build<K extends SliceComponentName>/);
297
- } finally {
298
- await cleanupTestProject(tmpRoot);
299
- }
300
- });
301
-
302
- test('ensureEditorConfigForTypes augments existing jsconfig include list', async () => {
303
- const tmpRoot = await createTestProject();
304
- const outputFile = path.join(tmpRoot, 'src', 'slice-build.generated.d.ts');
305
- const jsconfigPath = path.join(tmpRoot, 'jsconfig.json');
306
-
307
- try {
308
- fs.writeFileSync(outputFile, 'export {};\n', 'utf8');
309
- fs.writeFileSync(
310
- jsconfigPath,
311
- JSON.stringify(
312
- {
313
- compilerOptions: {
314
- allowJs: true
315
- },
316
- include: ['src/Components/**/*.js', 'src/**/*.js', 'api/**/*.js', 'tests/**/*.js']
317
- },
318
- null,
319
- 2
320
- ),
321
- 'utf8'
322
- );
323
-
324
- const result = await ensureEditorConfigForTypes({
325
- projectRoot: tmpRoot,
326
- outputPath: outputFile
327
- });
328
-
329
- assert.equal(result.mode, 'updated_jsconfig');
330
-
331
- const jsconfig = JSON.parse(fs.readFileSync(jsconfigPath, 'utf8'));
332
- assert.equal(jsconfig.include.includes('src/Components/**/*.js'), true);
333
- assert.equal(jsconfig.include.includes('src/**/*.d.ts'), true);
334
- assert.equal(jsconfig.include.includes('src/**/*.js'), false);
335
- assert.equal(jsconfig.include.includes('api/**/*.js'), false);
336
- assert.equal(jsconfig.include.includes('tests/**/*.js'), false);
337
- assert.equal(jsconfig.compilerOptions.allowJs, true);
338
- assert.equal(jsconfig.compilerOptions.checkJs, true);
339
- assert.equal(jsconfig.compilerOptions.noImplicitAny, false);
340
- assert.equal(jsconfig.compilerOptions.strictNullChecks, false);
341
- assert.equal(jsconfig.compilerOptions.strict, false);
342
- assert.equal(Array.isArray(jsconfig.exclude), true);
343
- assert.equal(jsconfig.exclude.includes('src/libs/**'), true);
344
- assert.equal(jsconfig.exclude.includes('tests/**'), true);
345
- } finally {
346
- await cleanupTestProject(tmpRoot);
347
- }
348
- });