@ape-egg/vibe 2.1.22 → 3.0.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.
- package/README.md +112 -5
- package/boot.js +4 -4
- package/component.js +27 -29
- package/hot-module-refresh.js +4 -4
- package/index.js +26 -17
- package/llms.txt +36 -5
- package/package.json +20 -14
- package/runtime/affected.js +159 -36
- package/runtime/cleanup.js +45 -1
- package/runtime/component.js +360 -98
- package/runtime/conditionals.js +111 -14
- package/runtime/debug.js +24 -0
- package/runtime/dispatch.js +172 -0
- package/runtime/hydrate.js +277 -110
- package/runtime/index.js +189 -65
- package/runtime/iterate.js +125 -50
- package/runtime/iteration-utils.js +59 -8
- package/runtime/manifest.js +77 -2
- package/runtime/parse.js +81 -11
- package/runtime/pre-compiled-iterations.js +19 -6
- package/runtime/pre-compiled-manifest.js +13 -4
- package/runtime/staging.js +153 -0
- package/runtime/state.js +31 -0
- package/runtime/tracking.js +173 -0
- package/runtime/utils.js +155 -78
- package/spa.js +206 -0
- package/vibe.css +8 -4
- package/CHANGELOG.md +0 -1159
- package/ROADMAP.md +0 -397
- package/compiler/bin/vibe-compile.js +0 -121
- package/compiler/native/.gitkeep +0 -0
- package/compiler/native/vibe-compiler-darwin-arm64 +0 -0
- package/compiler/native/vibe-compiler-linux-x64 +0 -0
- package/compiler/src/Cargo.lock +0 -2023
- package/compiler/src/Cargo.toml +0 -38
- package/compiler/src/compiler/PRE-RENDERING-IMPLEMENTATION.md +0 -241
- package/compiler/src/compiler/binding_case.rs +0 -88
- package/compiler/src/compiler/compile.rs +0 -2522
- package/compiler/src/compiler/component_tagger.rs +0 -469
- package/compiler/src/compiler/iteration_optimizer.rs +0 -455
- package/compiler/src/compiler/js_analyzer.rs +0 -715
- package/compiler/src/compiler/manifest_builder.rs +0 -693
- package/compiler/src/compiler/mod.rs +0 -15
- package/compiler/src/compiler/name_binding_protect.rs +0 -207
- package/compiler/src/compiler/reassignment_analyzer.rs +0 -456
- package/compiler/src/compiler/state_extractor.rs +0 -263
- package/compiler/src/compiler/value_stamper.rs +0 -921
- package/compiler/src/compiler/watcher.rs +0 -1147
- package/compiler/src/config.rs +0 -239
- package/compiler/src/main.rs +0 -347
- package/compiler/src/parser/element.rs +0 -96
- package/compiler/src/parser/html.rs +0 -1004
- package/compiler/src/parser/mod.rs +0 -8
- package/runtime/pre-compiled-manifest.test.mjs +0 -58
- package/runtime/scope.js +0 -50
- package/test-results/.last-run.json +0 -4
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert';
|
|
2
|
-
|
|
3
|
-
// The module runs a top-level `await detectHyperspeed()` that touches the DOM,
|
|
4
|
-
// so stub the globals before importing it. querySelector returns truthy →
|
|
5
|
-
// skipNetwork → no import() probing during module init.
|
|
6
|
-
globalThis.window = { location: { pathname: '/' }, __ROUTE__: undefined };
|
|
7
|
-
globalThis.document = { querySelector: () => ({}) };
|
|
8
|
-
|
|
9
|
-
const { buildManifestCandidatePaths } = await import('./pre-compiled-manifest.js');
|
|
10
|
-
|
|
11
|
-
let passed = 0;
|
|
12
|
-
const test = (name, fn) => {
|
|
13
|
-
fn();
|
|
14
|
-
passed++;
|
|
15
|
-
console.log(` ok - ${name}`);
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
// Dynamic route: window.__ROUTE__ tells us the trailing segment is a param, so
|
|
19
|
-
// the very first candidate must be the tokenized `$` manifest — no literal
|
|
20
|
-
// `0.html.manifest.js` probes that are guaranteed to 404.
|
|
21
|
-
test('dynamic route resolves the $ manifest first (no literal probing)', () => {
|
|
22
|
-
const paths = buildManifestCandidatePaths('/brawlers/0', '/brawlers/:index');
|
|
23
|
-
assert.strictEqual(paths[0], '/vibe-hyperspeed/brawlers/$.html.manifest.js');
|
|
24
|
-
assert.ok(
|
|
25
|
-
!paths.includes('/vibe-hyperspeed/brawlers/0.html.manifest.js') ||
|
|
26
|
-
paths.indexOf('/vibe-hyperspeed/brawlers/$.html.manifest.js') <
|
|
27
|
-
paths.indexOf('/vibe-hyperspeed/brawlers/0.html.manifest.js'),
|
|
28
|
-
'tokenized path must come before any literal path',
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// Mid-path params tokenize by position, not just the filename.
|
|
33
|
-
test('tokenizes only the param segments named by the route', () => {
|
|
34
|
-
const paths = buildManifestCandidatePaths(
|
|
35
|
-
'/_internal/characters/troll',
|
|
36
|
-
'/_internal/characters/:key',
|
|
37
|
-
);
|
|
38
|
-
assert.strictEqual(
|
|
39
|
-
paths[0],
|
|
40
|
-
'/vibe-hyperspeed/_internal/characters/$.html.manifest.js',
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// Static page: no route hint, behaviour unchanged, no duplicate candidates.
|
|
45
|
-
test('static top-level page resolves cleanly with no duplicates', () => {
|
|
46
|
-
const paths = buildManifestCandidatePaths('/armory', null);
|
|
47
|
-
assert.ok(paths.includes('/vibe-hyperspeed/armory.html.manifest.js'));
|
|
48
|
-
assert.strictEqual(paths.length, new Set(paths).size, 'no duplicate candidates');
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
// Subdirectory static page: strategies 2 and 3 collapse to the same URL — it
|
|
52
|
-
// must be probed once, not twice.
|
|
53
|
-
test('subdirectory page dedupes identical candidates', () => {
|
|
54
|
-
const paths = buildManifestCandidatePaths('/foo/bar', null);
|
|
55
|
-
assert.strictEqual(paths.length, new Set(paths).size, 'no duplicate candidates');
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
console.log(`\n${passed} passed`);
|
package/runtime/scope.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
// Scope resolution for component state
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Find the component ID that owns this element
|
|
5
|
-
* Finds nearest ancestor with data-vibe-component-id (set by component.js)
|
|
6
|
-
* @param {Element} element - DOM element to find component for
|
|
7
|
-
* @returns {string|null} - Component ID or null if not in component scope
|
|
8
|
-
*/
|
|
9
|
-
export const findComponentId = (element) => {
|
|
10
|
-
if (!element || !element.closest) return null;
|
|
11
|
-
|
|
12
|
-
// Find nearest component wrapper (tagged by component.js)
|
|
13
|
-
const wrapper = element.closest('[data-vibe-component-id]');
|
|
14
|
-
return wrapper ? wrapper.getAttribute('data-vibe-component-id') : null;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Resolve a property path with component scope fallback
|
|
19
|
-
* Checks component state first, then global state
|
|
20
|
-
* @param {string} path - Property path (e.g., "count" or "user.name")
|
|
21
|
-
* @param {Element} element - DOM element for context
|
|
22
|
-
* @param {object} globalState - Global $ object
|
|
23
|
-
* @returns {*} - Resolved value
|
|
24
|
-
*/
|
|
25
|
-
export const resolveWithScope = (path, element, globalState) => {
|
|
26
|
-
const componentId = findComponentId(element);
|
|
27
|
-
|
|
28
|
-
if (componentId && globalState[componentId]) {
|
|
29
|
-
// Check component state first
|
|
30
|
-
const componentState = globalState[componentId];
|
|
31
|
-
const value = resolvePath(path, componentState);
|
|
32
|
-
|
|
33
|
-
if (value !== undefined) {
|
|
34
|
-
return value;
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
// Fallback to global state
|
|
39
|
-
return resolvePath(path, globalState);
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Resolve a dot-notation path in an object
|
|
44
|
-
* @param {string} path - Property path
|
|
45
|
-
* @param {object} obj - Object to resolve path in
|
|
46
|
-
* @returns {*} - Resolved value or undefined
|
|
47
|
-
*/
|
|
48
|
-
const resolvePath = (path, obj) => {
|
|
49
|
-
return path.split('.').reduce((current, key) => current?.[key], obj);
|
|
50
|
-
};
|