round-core 0.0.7 → 0.0.9

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 (76) hide show
  1. package/README.md +62 -41
  2. package/dist/index.d.ts +341 -341
  3. package/dist/index.js +211 -192
  4. package/dist/vite-plugin.js +52 -3
  5. package/package.json +7 -4
  6. package/.github/workflows/benchmarks.yml +0 -44
  7. package/Round.png +0 -0
  8. package/benchmarks/apps/react/index.html +0 -9
  9. package/benchmarks/apps/react/main.jsx +0 -25
  10. package/benchmarks/apps/react/vite.config.js +0 -12
  11. package/benchmarks/apps/round/index.html +0 -11
  12. package/benchmarks/apps/round/main.jsx +0 -22
  13. package/benchmarks/apps/round/vite.config.js +0 -15
  14. package/benchmarks/bun.lock +0 -497
  15. package/benchmarks/dist-bench/react/assets/index-9KGqIPOU.js +0 -8
  16. package/benchmarks/dist-bench/react/index.html +0 -10
  17. package/benchmarks/dist-bench/round/assets/index-CBBIRhox.js +0 -52
  18. package/benchmarks/dist-bench/round/index.html +0 -8
  19. package/benchmarks/package.json +0 -22
  20. package/benchmarks/scripts/measure-build.js +0 -64
  21. package/benchmarks/tests/runtime.bench.js +0 -51
  22. package/benchmarks/vitest.config.js +0 -8
  23. package/bun.lock +0 -425
  24. package/cli.js +0 -2
  25. package/extension/.vscodeignore +0 -5
  26. package/extension/LICENSE +0 -21
  27. package/extension/cgmanifest.json +0 -45
  28. package/extension/extension.js +0 -163
  29. package/extension/images/round-config-dark.svg +0 -10
  30. package/extension/images/round-config-light.svg +0 -10
  31. package/extension/images/round-dark.svg +0 -10
  32. package/extension/images/round-light.svg +0 -10
  33. package/extension/javascript-language-configuration.json +0 -241
  34. package/extension/package-lock.json +0 -97
  35. package/extension/package.json +0 -119
  36. package/extension/package.nls.json +0 -4
  37. package/extension/round-0.1.0.vsix +0 -0
  38. package/extension/round-lsp/package-lock.json +0 -185
  39. package/extension/round-lsp/package.json +0 -21
  40. package/extension/round-lsp/src/round-transformer-lsp.js +0 -248
  41. package/extension/round-lsp/src/server.js +0 -396
  42. package/extension/snippets/javascript.code-snippets +0 -266
  43. package/extension/snippets/round.code-snippets +0 -109
  44. package/extension/syntaxes/JavaScript.tmLanguage.json +0 -6001
  45. package/extension/syntaxes/JavaScriptReact.tmLanguage.json +0 -6066
  46. package/extension/syntaxes/Readme.md +0 -12
  47. package/extension/syntaxes/Regular Expressions (JavaScript).tmLanguage +0 -237
  48. package/extension/syntaxes/Round.tmLanguage.json +0 -290
  49. package/extension/syntaxes/RoundInject.tmLanguage.json +0 -20
  50. package/extension/tags-language-configuration.json +0 -152
  51. package/extension/temp_astro/package-lock.json +0 -912
  52. package/extension/temp_astro/package.json +0 -16
  53. package/extension/types/round-core.d.ts +0 -326
  54. package/index.js +0 -2
  55. package/logo.svg +0 -10
  56. package/src/cli.js +0 -608
  57. package/src/compiler/index.js +0 -2
  58. package/src/compiler/transformer.js +0 -443
  59. package/src/compiler/vite-plugin.js +0 -472
  60. package/src/index.d.ts +0 -341
  61. package/src/index.js +0 -45
  62. package/src/runtime/context.js +0 -101
  63. package/src/runtime/dom.js +0 -403
  64. package/src/runtime/error-boundary.js +0 -48
  65. package/src/runtime/error-reporter.js +0 -13
  66. package/src/runtime/error-store.js +0 -85
  67. package/src/runtime/errors.js +0 -152
  68. package/src/runtime/lifecycle.js +0 -142
  69. package/src/runtime/markdown.js +0 -72
  70. package/src/runtime/router.js +0 -468
  71. package/src/runtime/signals.js +0 -548
  72. package/src/runtime/store.js +0 -215
  73. package/src/runtime/suspense.js +0 -128
  74. package/vite.config.build.js +0 -48
  75. package/vite.config.js +0 -10
  76. package/vitest.config.js +0 -8
@@ -1,548 +0,0 @@
1
- import { onMount, triggerUpdate, getCurrentComponent } from './lifecycle.js';
2
- import { reportErrorSafe } from './error-reporter.js';
3
-
4
- let context = [];
5
-
6
- function isPromiseLike(v) {
7
- return v && (typeof v === 'object' || typeof v === 'function') && typeof v.then === 'function';
8
- }
9
-
10
- function subscribe(running, subscriptions) {
11
- subscriptions.add(running);
12
- running.dependencies.add(subscriptions);
13
- }
14
-
15
- /**
16
- * Run a function without tracking any signals it reads.
17
- * Any signals accessed inside `fn` will not become dependencies of the current effect.
18
- * @template T
19
- * @param {() => T} fn The function to execute.
20
- * @returns {T} The return value of `fn`.
21
- */
22
- export function untrack(fn) {
23
- context.push(null);
24
- try {
25
- return typeof fn === 'function' ? fn() : undefined;
26
- } finally {
27
- context.pop();
28
- }
29
- }
30
-
31
- /**
32
- * Create a reactive side-effect that runs whenever its signal dependencies change.
33
- * @param {(() => any) | any[]} arg1 Either the callback function or an array of explicit dependencies.
34
- * @param {(() => any)} [arg2] The callback function if the first argument was explicit dependencies.
35
- * @param {object} [arg3] Optional configuration (e.g., { onLoad: false }).
36
- * @returns {() => void} A function to stop and cleanup the effect.
37
- */
38
- export function effect(arg1, arg2, arg3) {
39
- let callback;
40
- let explicitDeps = null;
41
- let options = { onLoad: true };
42
-
43
- let owner = getCurrentComponent();
44
-
45
- if (typeof arg1 === 'function') {
46
- callback = arg1;
47
- if (arg2 && typeof arg2 === 'object') {
48
- options = { ...options, ...arg2 };
49
- }
50
- } else {
51
- explicitDeps = arg1;
52
- callback = arg2;
53
- if (arg3 && typeof arg3 === 'object') {
54
- options = { ...options, ...arg3 };
55
- }
56
- }
57
-
58
- const execute = () => {
59
- if (typeof execute._cleanup === 'function') {
60
- try {
61
- execute._cleanup();
62
- } catch (e) {
63
- const name = owner ? (owner.name ?? 'Anonymous') : null;
64
- reportErrorSafe(e, { phase: 'effect.cleanup', component: name });
65
- }
66
- execute._cleanup = null;
67
- }
68
-
69
- cleanup(execute);
70
- context.push(execute);
71
- try {
72
- if (explicitDeps) {
73
- if (Array.isArray(explicitDeps)) {
74
- explicitDeps.forEach(dep => {
75
- if (typeof dep === 'function') dep();
76
- });
77
- } else if (typeof explicitDeps === 'function') {
78
- explicitDeps();
79
- }
80
- }
81
- if (typeof callback === 'function') {
82
- const res = callback();
83
- if (typeof res === 'function') {
84
- execute._cleanup = res;
85
- }
86
- }
87
-
88
- if (owner && owner.isMounted) triggerUpdate(owner);
89
-
90
- } catch (e) {
91
- if (isPromiseLike(e)) throw e;
92
- const name = owner ? (owner.name ?? 'Anonymous') : null;
93
- reportErrorSafe(e, { phase: 'effect', component: name });
94
- } finally {
95
- context.pop();
96
- }
97
- };
98
-
99
- execute.dependencies = new Set();
100
- execute._cleanup = null;
101
-
102
- if (options.onLoad) {
103
- onMount(execute);
104
- } else {
105
- execute();
106
- }
107
-
108
- return () => {
109
- if (typeof execute._cleanup === 'function') {
110
- try {
111
- execute._cleanup();
112
- } catch (e) {
113
- const name = owner ? (owner.name ?? 'Anonymous') : null;
114
- reportErrorSafe(e, { phase: 'effect.cleanup', component: name });
115
- }
116
- }
117
- execute._cleanup = null;
118
- cleanup(execute);
119
- };
120
- }
121
-
122
- function cleanup(running) {
123
- running.dependencies.forEach(dep => dep.delete(running));
124
- running.dependencies.clear();
125
- }
126
-
127
- function defineBindMarkerIfNeeded(source, target) {
128
- if (source && source.bind === true) {
129
- try {
130
- Object.defineProperty(target, 'bind', {
131
- enumerable: true,
132
- configurable: false,
133
- writable: false,
134
- value: true
135
- });
136
- } catch {
137
- try { target.bind = true; } catch { }
138
- }
139
- }
140
- }
141
-
142
- function attachHelpers(s) {
143
- if (!s || typeof s !== 'function') return s;
144
- if (typeof s.transform === 'function' && typeof s.validate === 'function' && typeof s.$pick === 'function') return s;
145
-
146
- s.$pick = (p) => {
147
- return pick(s, p);
148
- };
149
-
150
- s.transform = (fromInput, toOutput) => {
151
- const fromFn = typeof fromInput === 'function' ? fromInput : (v) => v;
152
- const toFn = typeof toOutput === 'function' ? toOutput : (v) => v;
153
-
154
- const wrapped = function (...args) {
155
- if (args.length > 0) {
156
- return s(fromFn(args[0]));
157
- }
158
- return toFn(s());
159
- };
160
-
161
- wrapped.peek = () => toFn(s.peek());
162
- Object.defineProperty(wrapped, 'value', {
163
- enumerable: true,
164
- get() {
165
- return wrapped.peek();
166
- },
167
- set(v) {
168
- wrapped(v);
169
- }
170
- });
171
-
172
- defineBindMarkerIfNeeded(s, wrapped);
173
- return attachHelpers(wrapped);
174
- };
175
-
176
- s.validate = (validator, options = {}) => {
177
- const validateFn = typeof validator === 'function' ? validator : null;
178
- const error = signal(null);
179
- const validateOn = (options && typeof options === 'object' && typeof options.validateOn === 'string')
180
- ? options.validateOn
181
- : 'input';
182
- const validateInitial = Boolean(options && typeof options === 'object' && options.validateInitial);
183
-
184
- const wrapped = function (...args) {
185
- if (args.length > 0) {
186
- const next = args[0];
187
- if (validateFn) {
188
- let res = true;
189
- try {
190
- res = validateFn(next, s.peek());
191
- } catch {
192
- res = 'Invalid value';
193
- }
194
-
195
- if (res === true || res === undefined || res === null) {
196
- error(null);
197
- return s(next);
198
- }
199
-
200
- if (typeof res === 'string' && res.length) {
201
- error(res);
202
- } else {
203
- error('Invalid value');
204
- }
205
- return s.peek();
206
- }
207
-
208
- error(null);
209
- return s(next);
210
- }
211
- return s();
212
- };
213
-
214
- wrapped.check = () => {
215
- if (!validateFn) {
216
- error(null);
217
- return true;
218
- }
219
- const cur = s.peek();
220
- let res = true;
221
- try {
222
- res = validateFn(cur, cur);
223
- } catch {
224
- res = 'Invalid value';
225
- }
226
- if (res === true || res === undefined || res === null) {
227
- error(null);
228
- return true;
229
- }
230
- if (typeof res === 'string' && res.length) error(res);
231
- else error('Invalid value');
232
- return false;
233
- };
234
-
235
- wrapped.peek = () => s.peek();
236
- Object.defineProperty(wrapped, 'value', {
237
- enumerable: true,
238
- get() {
239
- return wrapped.peek();
240
- },
241
- set(v) {
242
- wrapped(v);
243
- }
244
- });
245
-
246
- wrapped.error = error;
247
- wrapped.__round_validateOn = validateOn;
248
- if (validateInitial) {
249
- try { wrapped.check(); } catch { }
250
- }
251
- defineBindMarkerIfNeeded(s, wrapped);
252
- return attachHelpers(wrapped);
253
- };
254
-
255
- return s;
256
- }
257
-
258
- /**
259
- * Create a reactive signal.
260
- * @template T
261
- * @param {T} [initialValue] The starting value.
262
- * @returns {RoundSignal<T>} A signal function that reads/writes the value.
263
- */
264
- export function signal(initialValue) {
265
- let value = initialValue;
266
- const subscriptions = new Set();
267
-
268
- const read = () => {
269
- const running = context[context.length - 1];
270
- if (running) {
271
- subscribe(running, subscriptions);
272
- }
273
- return value;
274
- };
275
-
276
- const peek = () => value;
277
-
278
- const write = (newValue) => {
279
- if (value !== newValue) {
280
- value = newValue;
281
- [...subscriptions].forEach(sub => sub());
282
- }
283
- return value;
284
- };
285
-
286
- const signal = function (...args) {
287
- if (args.length > 0) {
288
- return write(args[0]);
289
- }
290
- return read();
291
- };
292
-
293
- Object.defineProperty(signal, 'value', {
294
- enumerable: true,
295
- get() {
296
- return peek();
297
- },
298
- set(v) {
299
- write(v);
300
- }
301
- });
302
-
303
- signal.peek = peek;
304
-
305
- return attachHelpers(signal);
306
- }
307
-
308
- /**
309
- * Create a bindable signal intended for two-way DOM bindings.
310
- * @template T
311
- * @param {T} [initialValue] The starting value.
312
- * @returns {RoundSignal<T>} A signal function marked as bindable.
313
- */
314
- export function bindable(initialValue) {
315
- const s = signal(initialValue);
316
- try {
317
- Object.defineProperty(s, 'bind', {
318
- enumerable: true,
319
- configurable: false,
320
- writable: false,
321
- value: true
322
- });
323
- } catch {
324
- // Fallback if defineProperty fails
325
- try { s.bind = true; } catch { }
326
- }
327
- return attachHelpers(s);
328
- }
329
-
330
- function isSignalLike(v) {
331
- return typeof v === 'function' && typeof v.peek === 'function' && ('value' in v);
332
- }
333
-
334
- function getIn(obj, path) {
335
- let cur = obj;
336
- for (const key of path) {
337
- if (cur == null) return undefined;
338
- cur = cur[key];
339
- }
340
- return cur;
341
- }
342
-
343
- function setIn(obj, path, value) {
344
- if (!Array.isArray(path) || path.length === 0) return value;
345
-
346
- const root = (obj && typeof obj === 'object') ? obj : {};
347
- const out = Array.isArray(root) ? root.slice() : { ...root };
348
-
349
- let curOut = out;
350
- let curIn = root;
351
-
352
- for (let i = 0; i < path.length - 1; i++) {
353
- const key = path[i];
354
- const nextIn = (curIn && typeof curIn === 'object') ? curIn[key] : undefined;
355
- const nextOut = (nextIn && typeof nextIn === 'object')
356
- ? (Array.isArray(nextIn) ? nextIn.slice() : { ...nextIn })
357
- : {};
358
-
359
- curOut[key] = nextOut;
360
- curOut = nextOut;
361
- curIn = nextIn;
362
- }
363
-
364
- curOut[path[path.length - 1]] = value;
365
- return out;
366
- }
367
-
368
- function parsePath(path) {
369
- if (Array.isArray(path)) return path.map(p => String(p));
370
- if (typeof path === 'string') return path.split('.').filter(Boolean);
371
- return [String(path)];
372
- }
373
-
374
- /**
375
- * Create a read/write view of a specific path within a signal object.
376
- * @param {RoundSignal<any>} root The source signal.
377
- * @param {string | string[]} path The property path (e.g., 'user.profile.name' or ['user', 'profile', 'name']).
378
- * @returns {RoundSignal<any>} A signal-like view of the path.
379
- */
380
- export function pick(root, path) {
381
- if (!isSignalLike(root)) {
382
- throw new Error('[round] pick(root, path) expects root to be a signal (use bindable.object(...) or signal({...})).');
383
- }
384
- const pathArr = parsePath(path);
385
-
386
- const view = function (...args) {
387
- if (args.length > 0) {
388
- const nextRoot = setIn(root.peek(), pathArr, args[0]);
389
- return root(nextRoot);
390
- }
391
- const v = root();
392
- return getIn(v, pathArr);
393
- };
394
-
395
- view.peek = () => getIn(root.peek(), pathArr);
396
- Object.defineProperty(view, 'value', {
397
- enumerable: true,
398
- get() {
399
- return view.peek();
400
- },
401
- set(v) {
402
- view(v);
403
- }
404
- });
405
-
406
- if (root.bind === true) {
407
- try {
408
- Object.defineProperty(view, 'bind', {
409
- enumerable: true,
410
- configurable: false,
411
- writable: false,
412
- value: true
413
- });
414
- } catch {
415
- try { view.bind = true; } catch { }
416
- }
417
- }
418
-
419
- return view;
420
- }
421
-
422
- function createBindableObjectProxy(root, basePath) {
423
- const cache = new Map();
424
-
425
- const handler = {
426
- get(_target, prop) {
427
- if (prop === Symbol.toStringTag) return 'BindableObject';
428
- if (prop === Symbol.iterator) return undefined;
429
- if (prop === 'peek') return () => (basePath.length ? pick(root, basePath).peek() : root.peek());
430
- if (prop === 'value') return (basePath.length ? pick(root, basePath).peek() : root.peek());
431
- if (prop === 'bind') return true;
432
- if (prop === '$pick') {
433
- return (p) => {
434
- const nextPath = basePath.concat(parsePath(p));
435
- return createBindableObjectProxy(root, nextPath);
436
- };
437
- }
438
- if (prop === '_root') return root;
439
- if (prop === '_path') return basePath.slice();
440
-
441
- // Allow calling the proxy (it's a function proxy below)
442
- if (prop === 'call' || prop === 'apply') {
443
- return Reflect.get(_target, prop);
444
- }
445
-
446
- const key = String(prop);
447
- const nextPath = basePath.concat(key);
448
- const cacheKey = nextPath.join('.');
449
- if (cache.has(cacheKey)) return cache.get(cacheKey);
450
-
451
- // If the stored value at this path is itself a signal/bindable, return it directly.
452
- // This enables bindable.object({ email: bindable('').validate(...) }) patterns.
453
- try {
454
- const stored = getIn(root.peek(), nextPath);
455
- if (isSignalLike(stored)) {
456
- cache.set(cacheKey, stored);
457
- return stored;
458
- }
459
- } catch {
460
- }
461
-
462
- const next = createBindableObjectProxy(root, nextPath);
463
- cache.set(cacheKey, next);
464
- return next;
465
- },
466
- set(_target, prop, value) {
467
- const key = String(prop);
468
- const nextPath = basePath.concat(key);
469
- try {
470
- const stored = getIn(root.peek(), nextPath);
471
- if (isSignalLike(stored)) {
472
- stored(value);
473
- return true;
474
- }
475
- } catch {
476
- }
477
- pick(root, nextPath)(value);
478
- return true;
479
- },
480
- has(_target, prop) {
481
- // IMPORTANT: Proxy invariants require that if the target has a non-configurable
482
- // property, the `has` trap must return true.
483
- try {
484
- if (Reflect.has(_target, prop)) return true;
485
- } catch {
486
- }
487
-
488
- const v = basePath.length ? pick(root, basePath).peek() : root.peek();
489
- return v != null && Object.prototype.hasOwnProperty.call(v, prop);
490
- }
491
- };
492
-
493
- // Function proxy so you can do user() / user.name() etc.
494
- const fn = function (...args) {
495
- if (args.length > 0) {
496
- if (basePath.length) return pick(root, basePath)(args[0]);
497
- return root(args[0]);
498
- }
499
- if (basePath.length) return pick(root, basePath)();
500
- return root();
501
- };
502
-
503
- // Make it signal-like
504
- fn.peek = () => (basePath.length ? pick(root, basePath).peek() : root.peek());
505
- Object.defineProperty(fn, 'value', {
506
- enumerable: true,
507
- get() {
508
- return fn.peek();
509
- },
510
- set(v) {
511
- fn(v);
512
- }
513
- });
514
-
515
- try {
516
- Object.defineProperty(fn, 'bind', {
517
- enumerable: true,
518
- configurable: false,
519
- writable: false,
520
- value: true
521
- });
522
- } catch {
523
- try { fn.bind = true; } catch { }
524
- }
525
-
526
- return new Proxy(fn, handler);
527
- }
528
-
529
- bindable.object = function (initialObject = {}) {
530
- const root = bindable((initialObject && typeof initialObject === 'object') ? initialObject : {});
531
- return createBindableObjectProxy(root, []);
532
- };
533
-
534
- /**
535
- * Create a read-only computed signal derived from other signals.
536
- * @template T
537
- * @param {() => T} fn A function that computes the value.
538
- * @returns {(() => T)} A function that returns the derived value.
539
- */
540
- export function derive(fn) {
541
- const derived = signal();
542
-
543
- effect(() => {
544
- derived(fn());
545
- }, { onLoad: false });
546
-
547
- return () => derived();
548
- }