@cfdez11/vex 0.8.3 → 0.9.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 (71) hide show
  1. package/dist/bin/vex.js +3 -0
  2. package/dist/client/services/cache.js +1 -0
  3. package/dist/client/services/hmr-client.js +1 -0
  4. package/dist/client/services/html.js +1 -0
  5. package/dist/client/services/hydrate-client-components.js +1 -0
  6. package/dist/client/services/hydrate.js +1 -0
  7. package/dist/client/services/index.js +1 -0
  8. package/dist/client/services/navigation/create-layouts.js +1 -0
  9. package/dist/client/services/navigation/create-navigation.js +1 -0
  10. package/dist/client/services/navigation/index.js +1 -0
  11. package/dist/client/services/navigation/link-interceptor.js +1 -0
  12. package/dist/client/services/navigation/metadata.js +1 -0
  13. package/dist/client/services/navigation/navigate.js +1 -0
  14. package/dist/client/services/navigation/prefetch.js +1 -0
  15. package/dist/client/services/navigation/render-page.js +1 -0
  16. package/dist/client/services/navigation/render-ssr.js +1 -0
  17. package/dist/client/services/navigation/router.js +1 -0
  18. package/dist/client/services/navigation/use-query-params.js +1 -0
  19. package/dist/client/services/navigation/use-route-params.js +1 -0
  20. package/dist/client/services/navigation.js +1 -0
  21. package/dist/client/services/reactive.js +1 -0
  22. package/dist/server/build-static.js +6 -0
  23. package/dist/server/index.js +4 -0
  24. package/dist/server/prebuild.js +1 -0
  25. package/dist/server/utils/cache.js +1 -0
  26. package/dist/server/utils/component-processor.js +68 -0
  27. package/dist/server/utils/data-cache.js +1 -0
  28. package/dist/server/utils/esbuild-plugin.js +1 -0
  29. package/dist/server/utils/files.js +28 -0
  30. package/dist/server/utils/hmr.js +1 -0
  31. package/dist/server/utils/router.js +11 -0
  32. package/dist/server/utils/streaming.js +1 -0
  33. package/dist/server/utils/template.js +1 -0
  34. package/package.json +8 -7
  35. package/bin/vex.js +0 -69
  36. package/client/favicon.ico +0 -0
  37. package/client/services/cache.js +0 -55
  38. package/client/services/hmr-client.js +0 -22
  39. package/client/services/html.js +0 -378
  40. package/client/services/hydrate-client-components.js +0 -97
  41. package/client/services/hydrate.js +0 -25
  42. package/client/services/index.js +0 -9
  43. package/client/services/navigation/create-layouts.js +0 -172
  44. package/client/services/navigation/create-navigation.js +0 -103
  45. package/client/services/navigation/index.js +0 -8
  46. package/client/services/navigation/link-interceptor.js +0 -39
  47. package/client/services/navigation/metadata.js +0 -23
  48. package/client/services/navigation/navigate.js +0 -64
  49. package/client/services/navigation/prefetch.js +0 -43
  50. package/client/services/navigation/render-page.js +0 -45
  51. package/client/services/navigation/render-ssr.js +0 -157
  52. package/client/services/navigation/router.js +0 -48
  53. package/client/services/navigation/use-query-params.js +0 -225
  54. package/client/services/navigation/use-route-params.js +0 -76
  55. package/client/services/navigation.js +0 -6
  56. package/client/services/reactive.js +0 -247
  57. package/server/build-static.js +0 -138
  58. package/server/index.js +0 -135
  59. package/server/prebuild.js +0 -13
  60. package/server/utils/cache.js +0 -89
  61. package/server/utils/component-processor.js +0 -1631
  62. package/server/utils/data-cache.js +0 -62
  63. package/server/utils/delay.js +0 -1
  64. package/server/utils/esbuild-plugin.js +0 -110
  65. package/server/utils/files.js +0 -845
  66. package/server/utils/hmr.js +0 -21
  67. package/server/utils/router.js +0 -375
  68. package/server/utils/streaming.js +0 -324
  69. package/server/utils/template.js +0 -274
  70. /package/{client → dist/client}/app.webmanifest +0 -0
  71. /package/{server → dist/server}/root.html +0 -0
@@ -1,62 +0,0 @@
1
- /**
2
- * In-process TTL cache for server-side data fetching.
3
- *
4
- * ISR pages regenerate periodically and call `getData` on every regeneration.
5
- * If multiple pages or multiple Suspense components call the same external API
6
- * (e.g. a weather API, a CMS), each regeneration fires N duplicate HTTP requests
7
- * even though the data is the same for all of them.
8
- *
9
- * `withCache(key, ttlSeconds, fn)` deduplicates these calls:
10
- * - On the first call for a given key it invokes `fn`, caches the result,
11
- * and returns it.
12
- * - Subsequent calls within the TTL window return the cached value directly,
13
- * with no I/O.
14
- * - After the TTL expires the next call re-fetches and refreshes the cache.
15
- *
16
- * Usage inside a `<script server>` getData function:
17
- *
18
- * async function getData({ req }) {
19
- * const weather = await withCache('weather:london', 60, () =>
20
- * fetch('https://api.example.com/weather?city=london').then(r => r.json())
21
- * );
22
- * return { weather };
23
- * }
24
- *
25
- * `withCache` is automatically available in every server script — no import needed.
26
- *
27
- * Key: any string that uniquely identifies the data source + parameters
28
- * TTL: seconds the cached value is considered fresh
29
- * fn: zero-argument function that returns a value or a Promise<value>
30
- */
31
-
32
- /** @type {Map<string, { value: any, expiresAt: number }>} */
33
- const cache = new Map();
34
-
35
- /**
36
- * Returns a cached value for `key` if still fresh, otherwise calls `fn`,
37
- * stores the result, and returns it.
38
- *
39
- * @template T
40
- * @param {string} key - Unique cache key.
41
- * @param {number} ttlSeconds - Seconds before the cached value expires.
42
- * @param {() => T | Promise<T>} fn - Fetcher called on a cache miss.
43
- * @returns {T | Promise<T>}
44
- */
45
- export function withCache(key, ttlSeconds, fn) {
46
- const entry = cache.get(key);
47
- if (entry && Date.now() < entry.expiresAt) {
48
- return entry.value;
49
- }
50
-
51
- const result = fn();
52
-
53
- if (result instanceof Promise) {
54
- return result.then((value) => {
55
- cache.set(key, { value, expiresAt: Date.now() + ttlSeconds * 1000 });
56
- return value;
57
- });
58
- }
59
-
60
- cache.set(key, { value: result, expiresAt: Date.now() + ttlSeconds * 1000 });
61
- return result;
62
- }
@@ -1 +0,0 @@
1
- export const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -1,110 +0,0 @@
1
- import path from "path";
2
- import { SRC_DIR, PROJECT_ROOT } from "./files.js";
3
-
4
- /**
5
- * Creates the VexJS esbuild alias plugin.
6
- *
7
- * esbuild resolves imports by looking at the specifier string (e.g. "vex/reactive",
8
- * "./utils/counter", "lodash"). By default it only understands relative paths and
9
- * node_modules. This plugin teaches esbuild about the three VexJS-specific import
10
- * conventions so it can correctly bundle every <script client> block.
11
- *
12
- * The plugin intercepts imports at bundle time via onResolve hooks — each hook
13
- * matches a filter regex against the import specifier and returns either:
14
- * - { path, external: true } → esbuild leaves the import as-is in the output.
15
- * The browser resolves it at runtime from the URL.
16
- * - { path } → esbuild reads and inlines the file into the bundle.
17
- *
18
- * ─── Three categories of imports ────────────────────────────────────────────
19
- *
20
- * 1. Framework singletons (vex/*)
21
- * Examples: `import { reactive } from 'vex/reactive'`
22
- *
23
- * These are framework runtime files served statically at /_vexjs/services/.
24
- * They MUST be marked external so every component shares the same instance
25
- * at runtime. If esbuild inlined them, each component bundle would get its
26
- * own copy of reactive.js — reactive state would not be shared across
27
- * components on the same page and the entire reactivity system would break.
28
- *
29
- * The path is rewritten from the short alias to the browser-accessible URL:
30
- * vex/reactive → /_vexjs/services/reactive.js (external)
31
- *
32
- * 2. Project alias (@/*)
33
- * Example: `import { counter } from '@/utils/counter'`
34
- *
35
- * @/ is a shorthand for the project SRC_DIR root. These files are served as
36
- * singleton modules at /_vexjs/user/ — the browser's ES module cache ensures
37
- * all components share the same instance (same reactive state, same store).
38
- *
39
- * 3. Relative imports (./ and ../)
40
- * Example: `import { fn } from './helpers'`
41
- *
42
- * Treated the same as @/ — marked external and served at /_vexjs/user/.
43
- * This gives the same singleton guarantee as @/ imports: two components that
44
- * import the same file via different relative paths both resolve to the same
45
- * URL, so the browser module cache returns the same instance.
46
- *
47
- * Note: .vex component imports are stripped from clientImports before
48
- * reaching esbuild, so this hook only fires for .js user utility files.
49
- *
50
- * 4. npm packages (bare specifiers like 'lodash', 'date-fns')
51
- * Also resolved automatically by esbuild via node_modules lookup.
52
- * No custom hook is needed.
53
- *
54
- * @returns {import('esbuild').Plugin}
55
- */
56
- export function createVexAliasPlugin() {
57
- return {
58
- name: "vex-aliases",
59
- setup(build) {
60
- // ── Category 1a: vex/* ────────────────────────────────────────────────
61
- // Matches: 'vex/reactive', 'vex/html', 'vex/navigation', etc.
62
- // Rewrites to the browser URL and marks external so esbuild skips bundling.
63
- build.onResolve({ filter: /^vex\// }, (args) => {
64
- let mod = args.path.replace(/^vex\//, "");
65
- if (!path.extname(mod)) mod += ".js";
66
- return { path: `/_vexjs/services/${mod}`, external: true };
67
- });
68
-
69
- // ── Category 2: @/ project alias ─────────────────────────────────────
70
- // Matches: '@/utils/counter', '@/store/ui-state', etc.
71
- //
72
- // These are user JS utilities that must behave as singletons — all
73
- // components on a page must share the SAME module instance (same reactive
74
- // state, same store). If esbuild inlined them, each component bundle would
75
- // get its own copy and reactive state would not propagate across components.
76
- //
77
- // Solution: mark as external and rewrite to the browser-accessible URL
78
- // /_vexjs/user/<path>.js. The dev server serves those files on-the-fly with
79
- // import rewriting; the static build pre-copies them to dist/_vexjs/user/.
80
- // The browser's ES module cache ensures a single instance is shared.
81
- build.onResolve({ filter: /^@\// }, (args) => {
82
- let mod = args.path.slice(2); // strip leading @/
83
- if (!path.extname(mod)) mod += ".js";
84
- return { path: `/_vexjs/user/${mod}`, external: true };
85
- });
86
-
87
- // ── Category 3: relative imports (./ and ../) ─────────────────────────
88
- // Matches: './helpers', '../utils/format', etc.
89
- //
90
- // User JS files imported relatively are also served as singleton modules
91
- // at /_vexjs/user/<resolved-path>.js. This mirrors Vue + Vite: every source
92
- // file gets its own URL, and the browser module cache ensures the same file
93
- // is always the same instance regardless of how it was imported.
94
- //
95
- // Files outside SRC_DIR (e.g. node_modules reached via ../../) fall through
96
- // to esbuild's default resolver and are bundled inline as usual.
97
- build.onResolve({ filter: /^\.\.?\// }, (args) => {
98
- let resolved = path.resolve(args.resolveDir, args.path);
99
- if (!path.extname(resolved)) resolved += ".js";
100
-
101
- // Only intercept .js user files — anything else (CSS, JSON, non-user) falls through
102
- if (!resolved.endsWith(".js")) return;
103
- if (!resolved.startsWith(SRC_DIR) && !resolved.startsWith(PROJECT_ROOT)) return;
104
-
105
- const rel = path.relative(SRC_DIR, resolved).replace(/\\/g, "/");
106
- return { path: `/_vexjs/user/${rel}`, external: true };
107
- });
108
- },
109
- };
110
- }