rip-lang 3.13.83 → 3.13.85
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 +7 -7
- package/docs/dist/rip.js +152 -132
- package/docs/dist/rip.min.js +140 -161
- package/docs/dist/rip.min.js.br +0 -0
- package/package.json +1 -1
- package/src/browser.js +117 -74
package/docs/dist/rip.min.js.br
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/browser.js
CHANGED
|
@@ -26,9 +26,11 @@ const dedent = s => {
|
|
|
26
26
|
return s.replace(RegExp(`^[ \t]{${i}}`, 'gm'), '').trim();
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
// Browser runtime: collect all
|
|
30
|
-
//
|
|
31
|
-
//
|
|
29
|
+
// Browser runtime: collect all sources (inline scripts, data-src files, bundles),
|
|
30
|
+
// compile them in a shared scope, and execute as one async IIFE.
|
|
31
|
+
//
|
|
32
|
+
// data-src URLs ending in .rip are fetched as individual source files.
|
|
33
|
+
// All other URLs are fetched as JSON bundles containing multiple files.
|
|
32
34
|
async function processRipScripts() {
|
|
33
35
|
const sources = [];
|
|
34
36
|
|
|
@@ -51,99 +53,141 @@ async function processRipScripts() {
|
|
|
51
53
|
}
|
|
52
54
|
}
|
|
53
55
|
|
|
54
|
-
// Step 3: Fetch externals
|
|
56
|
+
// Step 3: Fetch externals — .rip URLs as source text, others as JSON bundles
|
|
55
57
|
if (sources.length > 0) {
|
|
56
|
-
await Promise.
|
|
58
|
+
const results = await Promise.allSettled(sources.map(async (s) => {
|
|
57
59
|
if (!s.url) return;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
console.error(`Rip: failed to fetch ${s.url} (${res.status})`);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
60
|
+
const res = await fetch(s.url);
|
|
61
|
+
if (!res.ok) throw new Error(`${s.url} (${res.status})`);
|
|
62
|
+
if (s.url.endsWith('.rip')) {
|
|
64
63
|
s.code = await res.text();
|
|
65
|
-
}
|
|
66
|
-
|
|
64
|
+
} else {
|
|
65
|
+
const bundle = await res.json();
|
|
66
|
+
s.bundle = bundle;
|
|
67
67
|
}
|
|
68
68
|
}));
|
|
69
|
+
for (const r of results) {
|
|
70
|
+
if (r.status === 'rejected') console.warn('Rip: fetch failed:', r.reason.message);
|
|
71
|
+
}
|
|
69
72
|
|
|
70
|
-
|
|
71
|
-
const
|
|
73
|
+
// Separate bundles from individual sources
|
|
74
|
+
const bundles = [];
|
|
75
|
+
const individual = [];
|
|
72
76
|
for (const s of sources) {
|
|
73
|
-
if (
|
|
74
|
-
|
|
75
|
-
const js = compileToJS(s.code, opts);
|
|
76
|
-
compiled.push({ js, url: s.url || 'inline' });
|
|
77
|
-
} catch (e) {
|
|
78
|
-
console.error(`Rip compile error in ${s.url || 'inline'}:`, e.message);
|
|
79
|
-
}
|
|
77
|
+
if (s.bundle) bundles.push(s.bundle);
|
|
78
|
+
else if (s.code) individual.push(s);
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
81
|
+
const routerAttr = runtimeTag?.getAttribute('data-router');
|
|
82
|
+
const hasRouter = routerAttr != null;
|
|
83
|
+
|
|
84
|
+
// Step 3b: If data-router is present and we have a bundle, use launch()
|
|
85
|
+
// for full routing support. Otherwise compile everything upfront.
|
|
86
|
+
if (hasRouter && bundles.length > 0) {
|
|
87
|
+
// Compile non-bundle sources (inline scripts, individual .rip files)
|
|
88
|
+
const opts = { skipRuntimes: true, skipExports: true };
|
|
89
|
+
if (individual.length > 0) {
|
|
90
|
+
let js = '';
|
|
91
|
+
for (const s of individual) {
|
|
92
|
+
try { js += compileToJS(s.code, opts) + '\n'; }
|
|
93
|
+
catch (e) { console.error(`Rip compile error in ${s.url || 'inline'}:`, e.message); }
|
|
94
|
+
}
|
|
95
|
+
if (js) {
|
|
96
|
+
try { await (0, eval)(`(async()=>{\n${js}\n})()`); }
|
|
97
|
+
catch (e) { console.error('Rip runtime error:', e); }
|
|
91
98
|
}
|
|
92
|
-
|
|
93
|
-
globalThis.__ripApp = app;
|
|
94
|
-
if (typeof window !== 'undefined') window.app = app;
|
|
99
|
+
}
|
|
95
100
|
|
|
101
|
+
// Launch with the last bundle (app bundle) — handles router, renderer, stash
|
|
102
|
+
const ui = importRip.modules?.['ui.rip'];
|
|
103
|
+
if (ui?.launch) {
|
|
104
|
+
const appBundle = bundles[bundles.length - 1];
|
|
96
105
|
const persistAttr = runtimeTag.getAttribute('data-persist');
|
|
97
|
-
|
|
98
|
-
|
|
106
|
+
const launchOpts = { bundle: appBundle, hash: routerAttr === 'hash' };
|
|
107
|
+
if (persistAttr != null) launchOpts.persist = persistAttr === 'local' ? 'local' : true;
|
|
108
|
+
await ui.launch('', launchOpts);
|
|
109
|
+
}
|
|
110
|
+
} else {
|
|
111
|
+
// No routing — expand bundles into individual sources, compile everything
|
|
112
|
+
const expanded = [];
|
|
113
|
+
for (const b of bundles) {
|
|
114
|
+
for (const [name, code] of Object.entries(b.components || {})) {
|
|
115
|
+
expanded.push({ code, url: name });
|
|
116
|
+
}
|
|
117
|
+
if (b.data) {
|
|
118
|
+
const stateAttr = runtimeTag?.getAttribute('data-state');
|
|
119
|
+
let initial = {};
|
|
120
|
+
if (stateAttr) { try { initial = JSON.parse(stateAttr); } catch {} }
|
|
121
|
+
Object.assign(initial, b.data);
|
|
122
|
+
runtimeTag?.setAttribute('data-state', JSON.stringify(initial));
|
|
99
123
|
}
|
|
100
124
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
if (compiled.length > 0) {
|
|
104
|
-
let js = compiled.map(c => c.js).join('\n');
|
|
125
|
+
expanded.push(...individual);
|
|
105
126
|
|
|
106
|
-
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
127
|
+
const opts = { skipRuntimes: true, skipExports: true };
|
|
128
|
+
const compiled = [];
|
|
129
|
+
for (const s of expanded) {
|
|
130
|
+
if (!s.code) continue;
|
|
131
|
+
try {
|
|
132
|
+
const js = compileToJS(s.code, opts);
|
|
133
|
+
compiled.push({ js, url: s.url || 'inline' });
|
|
134
|
+
} catch (e) {
|
|
135
|
+
console.error(`Rip compile error in ${s.url || 'inline'}:`, e.message);
|
|
136
|
+
}
|
|
111
137
|
}
|
|
112
138
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
try {
|
|
121
|
-
catch (
|
|
139
|
+
// Create app stash
|
|
140
|
+
if (!globalThis.__ripApp && runtimeTag) {
|
|
141
|
+
const stashFn = globalThis.stash;
|
|
142
|
+
if (stashFn) {
|
|
143
|
+
let initial = {};
|
|
144
|
+
const stateAttr = runtimeTag.getAttribute('data-state');
|
|
145
|
+
if (stateAttr) {
|
|
146
|
+
try { initial = JSON.parse(stateAttr); }
|
|
147
|
+
catch (e) { console.error('Rip: invalid data-state JSON:', e.message); }
|
|
148
|
+
}
|
|
149
|
+
const app = stashFn({ data: initial });
|
|
150
|
+
globalThis.__ripApp = app;
|
|
151
|
+
if (typeof window !== 'undefined') window.app = app;
|
|
152
|
+
|
|
153
|
+
const persistAttr = runtimeTag.getAttribute('data-persist');
|
|
154
|
+
if (persistAttr != null && globalThis.persistStash) {
|
|
155
|
+
globalThis.persistStash(app, { local: persistAttr === 'local' });
|
|
122
156
|
}
|
|
123
|
-
} else {
|
|
124
|
-
console.error('Rip runtime error:', e);
|
|
125
157
|
}
|
|
126
158
|
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
159
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
160
|
+
// Execute all compiled code in shared scope
|
|
161
|
+
if (compiled.length > 0) {
|
|
162
|
+
let js = compiled.map(c => c.js).join('\n');
|
|
163
|
+
|
|
164
|
+
const mount = runtimeTag?.getAttribute('data-mount');
|
|
165
|
+
if (mount) {
|
|
166
|
+
const target = runtimeTag.getAttribute('data-target') || 'body';
|
|
167
|
+
js += `\n${mount}.mount(${JSON.stringify(target)});`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
await (0, eval)(`(async()=>{\n${js}\n})()`);
|
|
172
|
+
document.body.classList.add('ready');
|
|
173
|
+
} catch (e) {
|
|
174
|
+
if (e instanceof SyntaxError) {
|
|
175
|
+
console.error(`Rip syntax error in combined output: ${e.message}`);
|
|
176
|
+
for (const c of compiled) {
|
|
177
|
+
try { new Function(`(async()=>{\n${c.js}\n})()`); }
|
|
178
|
+
catch (e2) { console.error(` → source: ${c.url}`, e2.message); }
|
|
179
|
+
}
|
|
180
|
+
} else {
|
|
181
|
+
console.error('Rip runtime error:', e);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
142
185
|
}
|
|
143
186
|
}
|
|
144
187
|
|
|
145
188
|
// Step 6: data-reload enables SSE hot-reload from dev server
|
|
146
|
-
if (
|
|
189
|
+
// Skip if launch() was called — it connects its own SSE watch.
|
|
190
|
+
if (runtimeTag?.hasAttribute('data-reload') && !globalThis.__ripLaunched) {
|
|
147
191
|
let ready = false;
|
|
148
192
|
const es = new EventSource('/watch');
|
|
149
193
|
es.addEventListener('connected', () => {
|
|
@@ -233,9 +277,8 @@ if (typeof globalThis !== 'undefined') {
|
|
|
233
277
|
globalThis.__ripExports = { compile, compileToJS, formatSExpr, getStdlibCode, VERSION, BUILD_DATE, getReactiveRuntime, getComponentRuntime };
|
|
234
278
|
}
|
|
235
279
|
|
|
236
|
-
// Auto-process <script type="text/rip"> blocks and
|
|
237
|
-
// Deferred via queueMicrotask so bundled entry code
|
|
238
|
-
// importRip.modules) runs before script processing begins.
|
|
280
|
+
// Auto-process <script type="text/rip"> blocks and data-src sources.
|
|
281
|
+
// Deferred via queueMicrotask so bundled entry code runs before script processing.
|
|
239
282
|
if (typeof document !== 'undefined') {
|
|
240
283
|
globalThis.__ripScriptsReady = new Promise(resolve => {
|
|
241
284
|
const run = () => processRipScripts().then(resolve);
|