veryfront 0.1.1003 → 0.1.1004

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/esm/deno.js CHANGED
@@ -1,6 +1,6 @@
1
1
  export default {
2
2
  "name": "veryfront",
3
- "version": "0.1.1003",
3
+ "version": "0.1.1004",
4
4
  "license": "Apache-2.0",
5
5
  "nodeModulesDir": "auto",
6
6
  "minimumDependencyAge": {
@@ -1 +1 @@
1
- {"version":3,"file":"transpiler.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/transpiler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA6IvD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAwGlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
1
+ {"version":3,"file":"transpiler.d.ts","sourceRoot":"","sources":["../../../src/src/discovery/transpiler.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AA4MvD;;GAEG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,OAAO,CAAC,CAgIlB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
@@ -27,7 +27,50 @@ import * as evalMod from "../eval/index.js";
27
27
  import * as metricsMod from "../metrics/index.js";
28
28
  import * as schemasMod from "../schemas/index.js";
29
29
  import * as chatUploadsMod from "../chat/upload-handler.js";
30
+ // Keyed by entry file + entry source hash; each entry additionally records the
31
+ // bundled dependency contents it was built from and is only served while those
32
+ // still match (see findCachedModuleWithFreshDeps).
30
33
  const transpileCache = new Map();
34
+ const textEncoder = new TextEncoder();
35
+ async function hashSource(source) {
36
+ const digest = await dntShim.crypto.subtle.digest("SHA-256", textEncoder.encode(source));
37
+ return Array.from(new Uint8Array(digest), (byte) => byte.toString(16).padStart(2, "0")).join("");
38
+ }
39
+ /**
40
+ * Returns the first cached module whose recorded bundled-dependency contents
41
+ * still match what the current adapter serves. esbuild inlines relative
42
+ * imports into the bundle, so an unchanged entry file does not guarantee an
43
+ * unchanged module: a dependency edited by a new release (or differing between
44
+ * two projects that share the same entry source) must invalidate the entry.
45
+ */
46
+ async function findCachedModuleWithFreshDeps(entries, context) {
47
+ const hashByPath = new Map();
48
+ for (const entry of entries) {
49
+ let depsMatch = true;
50
+ for (const dep of entry.deps) {
51
+ let hash = hashByPath.get(dep.path);
52
+ if (!hashByPath.has(dep.path)) {
53
+ try {
54
+ const content = context.fsAdapter
55
+ ? await context.fsAdapter.readFile(dep.path)
56
+ : await createFileSystem().readTextFile(dep.path);
57
+ hash = await hashSource(content);
58
+ }
59
+ catch {
60
+ hash = undefined;
61
+ }
62
+ hashByPath.set(dep.path, hash);
63
+ }
64
+ if (hash === undefined || hash !== dep.hash) {
65
+ depsMatch = false;
66
+ break;
67
+ }
68
+ }
69
+ if (depsMatch)
70
+ return entry.module;
71
+ }
72
+ return undefined;
73
+ }
31
74
  // Setup veryfront modules as globals for compiled binary support
32
75
  let veryfrontGlobalsInitialized = false;
33
76
  /**
@@ -57,7 +100,7 @@ async function ensureVeryfrontGlobals() {
57
100
  /**
58
101
  * Create an esbuild plugin for resolving files via fsAdapter
59
102
  */
60
- function createFsAdapterPlugin(fsAdapter) {
103
+ function createFsAdapterPlugin(fsAdapter, onDependencyLoaded) {
61
104
  const existsCache = new Map();
62
105
  async function checkExists(filePath) {
63
106
  const cached = existsCache.get(filePath);
@@ -108,6 +151,7 @@ function createFsAdapterPlugin(fsAdapter) {
108
151
  build.onLoad({ filter: /.*/, namespace: "fsadapter" }, wrapWithCurrentContext(async (args) => {
109
152
  try {
110
153
  const content = await fsAdapter.readFile(args.path);
154
+ onDependencyLoaded?.(args.path, content);
111
155
  return {
112
156
  contents: content,
113
157
  loader: getEsbuildLoader(args.path),
@@ -131,9 +175,6 @@ function createFsAdapterPlugin(fsAdapter) {
131
175
  * Import and transpile a module for discovery
132
176
  */
133
177
  export async function importModule(file, context) {
134
- const cached = transpileCache.get(file);
135
- if (cached)
136
- return cached;
137
178
  // Ensure veryfront modules are available as globals for compiled binaries
138
179
  await ensureVeryfrontGlobals();
139
180
  const filePath = file.replace("file://", "");
@@ -149,6 +190,20 @@ export async function importModule(file, context) {
149
190
  cause: error,
150
191
  });
151
192
  }
193
+ // The cache key must include the source content: a shared hosted runtime
194
+ // process serves many projects and releases, and the same relative path
195
+ // (e.g. "tools/foo.ts") recurs across them. A path-only key keeps serving
196
+ // the stale module after a deploy and can hand one project's module to
197
+ // another project's discovery. The entry hash alone is still not enough —
198
+ // bundled relative imports are inlined into the module — so cached entries
199
+ // are only served after their recorded dependency contents re-verify.
200
+ const cacheKey = `${file} ${await hashSource(source)}`;
201
+ const cachedEntries = transpileCache.get(cacheKey);
202
+ if (cachedEntries) {
203
+ const cached = await findCachedModuleWithFreshDeps(cachedEntries, context);
204
+ if (cached)
205
+ return cached;
206
+ }
152
207
  const loader = getEsbuildLoader(filePath);
153
208
  await ensureDefaultBundlerContracts();
154
209
  const { build } = await import("../extensions/bundler/index.js");
@@ -160,8 +215,16 @@ export async function importModule(file, context) {
160
215
  const relativeImports = isDeno && !isDenoCompiled && !hasFsAdapter
161
216
  ? [...source.matchAll(/from\s+["'](\.\.[^"']+)["']/g)].map((m) => m[1]).filter(Boolean)
162
217
  : [];
163
- // Use fsAdapter plugin whenever a VFS adapter is available (regardless of runtime)
164
- const plugins = hasFsAdapter ? [createFsAdapterPlugin(context.fsAdapter)] : [];
218
+ // Use fsAdapter plugin whenever a VFS adapter is available (regardless of
219
+ // runtime), recording every bundled dependency for cache re-validation.
220
+ const bundledDeps = [];
221
+ const plugins = hasFsAdapter
222
+ ? [
223
+ createFsAdapterPlugin(context.fsAdapter, (path, content) => {
224
+ bundledDeps.push({ path, content });
225
+ }),
226
+ ]
227
+ : [];
165
228
  const result = await build({
166
229
  bundle: true,
167
230
  write: false,
@@ -218,7 +281,10 @@ export async function importModule(file, context) {
218
281
  const moduleUrl = pathHelper.toFileUrl(tempFile);
219
282
  moduleUrl.searchParams.set("v", String(Date.now()));
220
283
  const module = await import(moduleUrl.href);
221
- transpileCache.set(file, module);
284
+ const deps = await Promise.all(bundledDeps.map(async ({ path, content }) => ({ path, hash: await hashSource(content) })));
285
+ const entries = transpileCache.get(cacheKey) ?? [];
286
+ entries.push({ deps, module });
287
+ transpileCache.set(cacheKey, entries);
222
288
  return module;
223
289
  }
224
290
  finally {
@@ -1,3 +1,3 @@
1
1
  /** Shared version value. */
2
- export declare const VERSION = "0.1.1003";
2
+ export declare const VERSION = "0.1.1004";
3
3
  //# sourceMappingURL=version-constant.d.ts.map
@@ -1,4 +1,4 @@
1
1
  // Keep in sync with deno.json version.
2
2
  // scripts/release.ts updates this constant during releases.
3
3
  /** Shared version value. */
4
- export const VERSION = "0.1.1003";
4
+ export const VERSION = "0.1.1004";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "veryfront",
3
- "version": "0.1.1003",
3
+ "version": "0.1.1004",
4
4
  "description": "The simplest way to build AI-powered apps",
5
5
  "keywords": [
6
6
  "react",