slicejs-web-framework 4.0.1 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/opencode.json +14 -14
- package/LICENSE +21 -21
- package/README.md +97 -97
- package/Slice/Components/Structural/ContextManager/ContextManager.js +422 -422
- package/Slice/Components/Structural/ContextManager/ContextManagerDebugger.js +470 -470
- package/Slice/Components/Structural/Controller/Controller.js +1406 -1406
- package/Slice/Components/Structural/Controller/allowedValuesValidation.js +52 -52
- package/Slice/Components/Structural/Debugger/Debugger.html +72 -72
- package/Slice/Components/Structural/Debugger/Debugger.js +1505 -1505
- package/Slice/Components/Structural/EventManager/EventManager.js +651 -651
- package/Slice/Components/Structural/EventManager/EventManagerDebugger.js +985 -985
- package/Slice/Components/Structural/LeakInspector/LeakInspector.js +296 -296
- package/Slice/Components/Structural/Logger/Log.js +10 -10
- package/Slice/Components/Structural/Logger/LogViewer/LogViewer.js +662 -662
- package/Slice/Components/Structural/Logger/Logger.js +225 -225
- package/Slice/Components/Structural/Router/Router.js +810 -793
- package/Slice/Components/Structural/StylesManager/StylesManager.js +82 -82
- package/Slice/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +175 -162
- package/Slice/Slice.js +708 -685
- package/Slice/tests/build-bundled-component-without-category.test.js +103 -103
- package/Slice/tests/build-js-only-visual-components.test.js +144 -144
- package/Slice/tests/build-singleton.test.js +244 -244
- package/Slice/tests/bundle-v2-runtime-contract.test.js +747 -738
- package/Slice/tests/context-patch-use.test.js +95 -95
- package/Slice/tests/destroy-cascade.test.js +215 -215
- package/Slice/tests/event-emitters.test.js +79 -79
- package/Slice/tests/event-registry.test.js +141 -141
- package/Slice/tests/fixtures/real-runtime-loader.mjs +21 -21
- package/Slice/tests/leak-orphans.test.js +131 -131
- package/Slice/tests/props-allowed-values-validation.test.js +119 -119
- package/Slice/tests/public-env-runtime-accessors.test.js +44 -44
- package/Slice/tests/public-env-typed-accessors.test.js +66 -66
- package/Slice/tests/router-loading-finally.test.js +68 -68
- package/api/framework/devDepsOptimizer.js +335 -335
- package/api/framework/express.js +3 -3
- package/api/framework/precompressedStatic.js +93 -93
- package/api/framework/publicEnvResolver.js +123 -123
- package/api/framework/securityMiddleware.js +197 -197
- package/api/framework/server.js +411 -411
- package/api/index.js +7 -7
- package/api/tests/dev-deps-optimizer.test.js +137 -137
- package/api/tests/dev-server-external.test.js +56 -56
- package/api/tests/precompressed-static.test.js +119 -119
- package/api/tests/public-env-resolver.test.js +193 -193
- package/package.json +49 -49
- package/sliceConfig.schema.json +122 -122
- package/src/App/index.html +69 -69
- package/src/App/index.js +20 -20
- package/src/App/style.css +11 -11
- package/src/Components/AppComponents/AboutSection/AboutSection.css +9 -9
- package/src/Components/AppComponents/AboutSection/AboutSection.html +8 -8
- package/src/Components/AppComponents/AboutSection/AboutSection.js +12 -12
- package/src/Components/AppComponents/AppShell/AppShell.css +10 -10
- package/src/Components/AppComponents/AppShell/AppShell.html +4 -4
- package/src/Components/AppComponents/AppShell/AppShell.js +36 -36
- package/src/Components/AppComponents/HomeSection/HomeSection.css +20 -20
- package/src/Components/AppComponents/HomeSection/HomeSection.html +10 -10
- package/src/Components/AppComponents/HomeSection/HomeSection.js +19 -19
- package/src/Components/components.js +8 -8
- package/src/public/Styles/sliceStyles.css +34 -34
- package/src/public/Themes/Dark.css +42 -42
- package/src/public/Themes/Light.css +31 -31
- package/src/public/Themes/Slice.css +47 -47
- package/src/public/manifest.json +15 -15
- package/src/public/robots.txt +4 -4
- package/src/public/sitemap.xml +8 -8
- package/src/routes.js +9 -9
- package/src/sliceConfig.json +72 -72
- package/tests/router-build-failure.test.js +125 -0
- package/tests/router-emit-ordering.test.js +63 -63
- package/types/index.d.ts +219 -219
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
|
|
4
|
-
globalThis.alert = () => {};
|
|
5
|
-
|
|
6
|
-
const { default: Slice } = await import('../Slice.js');
|
|
7
|
-
|
|
8
|
-
function createSliceInstance() {
|
|
9
|
-
return new Slice({
|
|
10
|
-
paths: {},
|
|
11
|
-
themeManager: {},
|
|
12
|
-
stylesManager: {},
|
|
13
|
-
logger: {},
|
|
14
|
-
debugger: {},
|
|
15
|
-
loading: {},
|
|
16
|
-
events: {}
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
test('slice.env.get / has / all', () => {
|
|
21
|
-
const s = createSliceInstance();
|
|
22
|
-
s.setPublicEnv({ SLICE_PUBLIC_API_URL: 'https://api.example.com', INTERNAL: 'hidden' });
|
|
23
|
-
|
|
24
|
-
assert.equal(s.env.get('SLICE_PUBLIC_API_URL'), 'https://api.example.com');
|
|
25
|
-
assert.equal(s.env.get('SLICE_PUBLIC_MISSING', 'fb'), 'fb');
|
|
26
|
-
assert.equal(s.env.has('SLICE_PUBLIC_API_URL'), true);
|
|
27
|
-
assert.equal(s.env.has('SLICE_PUBLIC_MISSING'), false);
|
|
28
|
-
assert.deepEqual(s.env.all(), { SLICE_PUBLIC_API_URL: 'https://api.example.com' }); // only SLICE_PUBLIC_*
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
test('slice.env.bool parses truthy strings and falls back', () => {
|
|
32
|
-
const s = createSliceInstance();
|
|
33
|
-
s.setPublicEnv({
|
|
34
|
-
SLICE_PUBLIC_ON: 'true',
|
|
35
|
-
SLICE_PUBLIC_ON2: 'YES',
|
|
36
|
-
SLICE_PUBLIC_ON3: '1',
|
|
37
|
-
SLICE_PUBLIC_OFF: 'false',
|
|
38
|
-
SLICE_PUBLIC_EMPTY: ''
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
assert.equal(s.env.bool('SLICE_PUBLIC_ON'), true);
|
|
42
|
-
assert.equal(s.env.bool('SLICE_PUBLIC_ON2'), true);
|
|
43
|
-
assert.equal(s.env.bool('SLICE_PUBLIC_ON3'), true);
|
|
44
|
-
assert.equal(s.env.bool('SLICE_PUBLIC_OFF'), false);
|
|
45
|
-
assert.equal(s.env.bool('SLICE_PUBLIC_EMPTY', true), true); // empty → fallback
|
|
46
|
-
assert.equal(s.env.bool('SLICE_PUBLIC_MISSING'), false); // missing → default false
|
|
47
|
-
assert.equal(s.env.bool('SLICE_PUBLIC_MISSING', true), true); // missing → custom fallback
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test('slice.env.int parses integers and falls back', () => {
|
|
51
|
-
const s = createSliceInstance();
|
|
52
|
-
s.setPublicEnv({ SLICE_PUBLIC_TIMEOUT: '5000', SLICE_PUBLIC_BAD: 'nope' });
|
|
53
|
-
|
|
54
|
-
assert.equal(s.env.int('SLICE_PUBLIC_TIMEOUT'), 5000);
|
|
55
|
-
assert.equal(s.env.int('SLICE_PUBLIC_BAD', 10), 10); // non-numeric → fallback
|
|
56
|
-
assert.equal(s.env.int('SLICE_PUBLIC_MISSING', 42), 42); // missing → fallback
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test('slice.env.list splits CSV, trims, drops empties', () => {
|
|
60
|
-
const s = createSliceInstance();
|
|
61
|
-
s.setPublicEnv({ SLICE_PUBLIC_MODELS: ' a , b ,, c ', SLICE_PUBLIC_EMPTY: '' });
|
|
62
|
-
|
|
63
|
-
assert.deepEqual(s.env.list('SLICE_PUBLIC_MODELS'), ['a', 'b', 'c']);
|
|
64
|
-
assert.deepEqual(s.env.list('SLICE_PUBLIC_EMPTY', ['x']), ['x']); // empty → fallback
|
|
65
|
-
assert.deepEqual(s.env.list('SLICE_PUBLIC_MISSING'), []); // missing → default []
|
|
66
|
-
});
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
|
|
4
|
+
globalThis.alert = () => {};
|
|
5
|
+
|
|
6
|
+
const { default: Slice } = await import('../Slice.js');
|
|
7
|
+
|
|
8
|
+
function createSliceInstance() {
|
|
9
|
+
return new Slice({
|
|
10
|
+
paths: {},
|
|
11
|
+
themeManager: {},
|
|
12
|
+
stylesManager: {},
|
|
13
|
+
logger: {},
|
|
14
|
+
debugger: {},
|
|
15
|
+
loading: {},
|
|
16
|
+
events: {}
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
test('slice.env.get / has / all', () => {
|
|
21
|
+
const s = createSliceInstance();
|
|
22
|
+
s.setPublicEnv({ SLICE_PUBLIC_API_URL: 'https://api.example.com', INTERNAL: 'hidden' });
|
|
23
|
+
|
|
24
|
+
assert.equal(s.env.get('SLICE_PUBLIC_API_URL'), 'https://api.example.com');
|
|
25
|
+
assert.equal(s.env.get('SLICE_PUBLIC_MISSING', 'fb'), 'fb');
|
|
26
|
+
assert.equal(s.env.has('SLICE_PUBLIC_API_URL'), true);
|
|
27
|
+
assert.equal(s.env.has('SLICE_PUBLIC_MISSING'), false);
|
|
28
|
+
assert.deepEqual(s.env.all(), { SLICE_PUBLIC_API_URL: 'https://api.example.com' }); // only SLICE_PUBLIC_*
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('slice.env.bool parses truthy strings and falls back', () => {
|
|
32
|
+
const s = createSliceInstance();
|
|
33
|
+
s.setPublicEnv({
|
|
34
|
+
SLICE_PUBLIC_ON: 'true',
|
|
35
|
+
SLICE_PUBLIC_ON2: 'YES',
|
|
36
|
+
SLICE_PUBLIC_ON3: '1',
|
|
37
|
+
SLICE_PUBLIC_OFF: 'false',
|
|
38
|
+
SLICE_PUBLIC_EMPTY: ''
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
assert.equal(s.env.bool('SLICE_PUBLIC_ON'), true);
|
|
42
|
+
assert.equal(s.env.bool('SLICE_PUBLIC_ON2'), true);
|
|
43
|
+
assert.equal(s.env.bool('SLICE_PUBLIC_ON3'), true);
|
|
44
|
+
assert.equal(s.env.bool('SLICE_PUBLIC_OFF'), false);
|
|
45
|
+
assert.equal(s.env.bool('SLICE_PUBLIC_EMPTY', true), true); // empty → fallback
|
|
46
|
+
assert.equal(s.env.bool('SLICE_PUBLIC_MISSING'), false); // missing → default false
|
|
47
|
+
assert.equal(s.env.bool('SLICE_PUBLIC_MISSING', true), true); // missing → custom fallback
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('slice.env.int parses integers and falls back', () => {
|
|
51
|
+
const s = createSliceInstance();
|
|
52
|
+
s.setPublicEnv({ SLICE_PUBLIC_TIMEOUT: '5000', SLICE_PUBLIC_BAD: 'nope' });
|
|
53
|
+
|
|
54
|
+
assert.equal(s.env.int('SLICE_PUBLIC_TIMEOUT'), 5000);
|
|
55
|
+
assert.equal(s.env.int('SLICE_PUBLIC_BAD', 10), 10); // non-numeric → fallback
|
|
56
|
+
assert.equal(s.env.int('SLICE_PUBLIC_MISSING', 42), 42); // missing → fallback
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('slice.env.list splits CSV, trims, drops empties', () => {
|
|
60
|
+
const s = createSliceInstance();
|
|
61
|
+
s.setPublicEnv({ SLICE_PUBLIC_MODELS: ' a , b ,, c ', SLICE_PUBLIC_EMPTY: '' });
|
|
62
|
+
|
|
63
|
+
assert.deepEqual(s.env.list('SLICE_PUBLIC_MODELS'), ['a', 'b', 'c']);
|
|
64
|
+
assert.deepEqual(s.env.list('SLICE_PUBLIC_EMPTY', ['x']), ['x']); // empty → fallback
|
|
65
|
+
assert.deepEqual(s.env.list('SLICE_PUBLIC_MISSING'), []); // missing → default []
|
|
66
|
+
});
|
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import test from 'node:test';
|
|
2
|
-
import assert from 'node:assert/strict';
|
|
3
|
-
|
|
4
|
-
import Router from '../Components/Structural/Router/Router.js';
|
|
5
|
-
|
|
6
|
-
test('handleRoute stops loading when build throws on error path', async () => {
|
|
7
|
-
const originalSlice = globalThis.slice;
|
|
8
|
-
const originalDocument = globalThis.document;
|
|
9
|
-
|
|
10
|
-
const targetElement = {
|
|
11
|
-
innerHTML: 'existing',
|
|
12
|
-
appendChild() {},
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
globalThis.document = {
|
|
17
|
-
querySelector(selector) {
|
|
18
|
-
if (selector === '#app') {
|
|
19
|
-
return targetElement;
|
|
20
|
-
}
|
|
21
|
-
return null;
|
|
22
|
-
},
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
const loadingCalls = [];
|
|
26
|
-
|
|
27
|
-
globalThis.slice = {
|
|
28
|
-
loading: {
|
|
29
|
-
start() {
|
|
30
|
-
loadingCalls.push('start');
|
|
31
|
-
},
|
|
32
|
-
stop() {
|
|
33
|
-
loadingCalls.push('stop');
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
controller: {
|
|
37
|
-
getComponent() {
|
|
38
|
-
return null;
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
build: async () => {
|
|
42
|
-
throw new Error('boom');
|
|
43
|
-
},
|
|
44
|
-
router: {
|
|
45
|
-
activeRoute: null,
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const router = new Router([]);
|
|
50
|
-
|
|
51
|
-
await assert.rejects(
|
|
52
|
-
() =>
|
|
53
|
-
router.handleRoute(
|
|
54
|
-
{
|
|
55
|
-
component: 'Dashboard',
|
|
56
|
-
parentRoute: null,
|
|
57
|
-
},
|
|
58
|
-
{}
|
|
59
|
-
),
|
|
60
|
-
/boom/
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
assert.deepEqual(loadingCalls, ['start', 'stop']);
|
|
64
|
-
} finally {
|
|
65
|
-
globalThis.slice = originalSlice;
|
|
66
|
-
globalThis.document = originalDocument;
|
|
67
|
-
}
|
|
68
|
-
});
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
|
|
4
|
+
import Router from '../Components/Structural/Router/Router.js';
|
|
5
|
+
|
|
6
|
+
test('handleRoute stops loading when build throws on error path', async () => {
|
|
7
|
+
const originalSlice = globalThis.slice;
|
|
8
|
+
const originalDocument = globalThis.document;
|
|
9
|
+
|
|
10
|
+
const targetElement = {
|
|
11
|
+
innerHTML: 'existing',
|
|
12
|
+
appendChild() {},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
globalThis.document = {
|
|
17
|
+
querySelector(selector) {
|
|
18
|
+
if (selector === '#app') {
|
|
19
|
+
return targetElement;
|
|
20
|
+
}
|
|
21
|
+
return null;
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
const loadingCalls = [];
|
|
26
|
+
|
|
27
|
+
globalThis.slice = {
|
|
28
|
+
loading: {
|
|
29
|
+
start() {
|
|
30
|
+
loadingCalls.push('start');
|
|
31
|
+
},
|
|
32
|
+
stop() {
|
|
33
|
+
loadingCalls.push('stop');
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
controller: {
|
|
37
|
+
getComponent() {
|
|
38
|
+
return null;
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
build: async () => {
|
|
42
|
+
throw new Error('boom');
|
|
43
|
+
},
|
|
44
|
+
router: {
|
|
45
|
+
activeRoute: null,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const router = new Router([]);
|
|
50
|
+
|
|
51
|
+
await assert.rejects(
|
|
52
|
+
() =>
|
|
53
|
+
router.handleRoute(
|
|
54
|
+
{
|
|
55
|
+
component: 'Dashboard',
|
|
56
|
+
parentRoute: null,
|
|
57
|
+
},
|
|
58
|
+
{}
|
|
59
|
+
),
|
|
60
|
+
/boom/
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
assert.deepEqual(loadingCalls, ['start', 'stop']);
|
|
64
|
+
} finally {
|
|
65
|
+
globalThis.slice = originalSlice;
|
|
66
|
+
globalThis.document = originalDocument;
|
|
67
|
+
}
|
|
68
|
+
});
|