next-evolve 0.1.0 → 0.3.1
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 +55 -1
- package/dist/_virtual/_rolldown/runtime.js +12 -0
- package/dist/aggregate/attribution.d.ts +40 -0
- package/dist/aggregate/attribution.js +115 -0
- package/dist/aggregate/run.d.ts +21 -0
- package/dist/aggregate/run.js +139 -0
- package/dist/cli/aggregate.d.ts +9 -0
- package/dist/cli/aggregate.js +104 -0
- package/dist/cli/args.d.ts +12 -0
- package/dist/cli/args.js +23 -0
- package/dist/cli/cloud.d.ts +41 -0
- package/dist/cli/cloud.js +74 -0
- package/dist/cli/connect.d.ts +8 -0
- package/dist/cli/connect.js +46 -0
- package/dist/cli/detect.d.ts +26 -0
- package/dist/cli/detect.js +97 -0
- package/dist/cli/doctor.d.ts +34 -0
- package/dist/cli/doctor.js +230 -0
- package/dist/cli/env-file.d.ts +4 -0
- package/dist/cli/env-file.js +15 -0
- package/dist/cli/files.d.ts +25 -0
- package/dist/cli/files.js +173 -0
- package/dist/cli/index.js +73 -32
- package/dist/cli/init.d.ts +26 -0
- package/dist/cli/init.js +240 -0
- package/dist/cli/load-app.d.ts +19 -0
- package/dist/cli/load-app.js +67 -0
- package/dist/cli/migrate.d.ts +7 -0
- package/dist/cli/migrate.js +30 -0
- package/dist/cli/pages.d.ts +17 -0
- package/dist/cli/pages.js +304 -0
- package/dist/cli/plan.d.ts +27 -0
- package/dist/cli/plan.js +129 -0
- package/dist/cli/pull.d.ts +13 -0
- package/dist/cli/pull.js +62 -0
- package/dist/cli/push.d.ts +14 -0
- package/dist/cli/push.js +33 -0
- package/dist/cloud/manifest.d.ts +2 -0
- package/dist/cloud/manifest.js +6 -2
- package/dist/core/assign.d.ts +13 -1
- package/dist/core/assign.js +25 -3
- package/dist/db/writer.d.ts +2 -0
- package/dist/db/writer.js +1 -1
- package/dist/instrumentation/index.d.ts +3 -2
- package/dist/instrumentation/index.js +17 -2
- package/dist/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/lib/typescript.d.ts +11169 -0
- package/dist/proxy/index.d.ts +2 -2
- package/dist/proxy/index.js +1 -1
- package/dist/proxy/proxy.d.ts +7 -1
- package/dist/proxy/proxy.js +23 -6
- package/dist/react/render-bundle.d.ts +10 -4
- package/dist/react/render-bundle.js +34 -5
- package/dist/server/aggregate-route.d.ts +16 -0
- package/dist/server/aggregate-route.js +68 -0
- package/dist/server/collect.d.ts +16 -0
- package/dist/server/collect.js +34 -8
- package/dist/server/handler.d.ts +3 -2
- package/dist/server/handler.js +37 -4
- package/dist/server/sync-route.d.ts +28 -0
- package/dist/server/sync-route.js +100 -0
- package/dist/store/disk.d.ts +6 -0
- package/dist/store/disk.js +23 -0
- package/dist/store/fetch.d.ts +4 -0
- package/dist/store/fetch.js +36 -1
- package/dist/store/global-config.d.ts +39 -0
- package/dist/store/global-config.js +122 -0
- package/dist/store/memory.d.ts +11 -2
- package/dist/store/memory.js +6 -2
- package/dist/store/runtime.d.ts +14 -0
- package/dist/store/runtime.js +39 -7
- package/package.json +2 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { FetchBundleResult } from "./fetch.js";
|
|
2
|
+
type Env = Record<string, string | undefined>;
|
|
3
|
+
/** How often instances re-read Global Config. */
|
|
4
|
+
export declare const GLOBAL_CONFIG_TTL_MS = 10000;
|
|
5
|
+
/** Max wait for the first read on a cold start; then the build bundle serves. */
|
|
6
|
+
export declare const COLD_READ_CAP_MS = 20;
|
|
7
|
+
export declare const globalConfigItemKey: (site: string) => string;
|
|
8
|
+
export type GlobalConfigSettings = {
|
|
9
|
+
connectionString: string;
|
|
10
|
+
/** Write access (sync route only). */
|
|
11
|
+
id?: string;
|
|
12
|
+
apiToken?: string;
|
|
13
|
+
teamId?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Global Config settings when the app opted in: `store: "global-config"`, or
|
|
17
|
+
* `"auto"` with `EVOLVE_GLOBAL_CONFIG` (connection string) set.
|
|
18
|
+
*/
|
|
19
|
+
export declare function globalConfigSettings(store: "auto" | "memory" | "global-config" | undefined, env: Env): GlobalConfigSettings | null;
|
|
20
|
+
export type GlobalConfigReader = (key: string) => Promise<unknown>;
|
|
21
|
+
export declare function defaultReader(connectionString: string): GlobalConfigReader;
|
|
22
|
+
/**
|
|
23
|
+
* Fetcher for the memory store: reads Global Config every call; also asks the
|
|
24
|
+
* cloud when Global Config is empty or every `cloudEveryMs` (so a missed
|
|
25
|
+
* webhook or a stale item can't freeze the app), and returns the newer token.
|
|
26
|
+
*/
|
|
27
|
+
export declare function createGlobalConfigFetcher(opts: {
|
|
28
|
+
site: string;
|
|
29
|
+
read: GlobalConfigReader;
|
|
30
|
+
cloud?: (etag: string | null) => Promise<FetchBundleResult>;
|
|
31
|
+
cloudEveryMs: number;
|
|
32
|
+
now?: () => number;
|
|
33
|
+
}): (etag: string | null) => Promise<FetchBundleResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Writes the token to the site's item via the Vercel REST API (sync route).
|
|
36
|
+
* Never throws; returns whether the write succeeded.
|
|
37
|
+
*/
|
|
38
|
+
export declare function writeGlobalConfig(settings: GlobalConfigSettings, site: string, token: string, f?: typeof fetch): Promise<boolean>;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
// src/store/global-config.ts
|
|
2
|
+
/** How often instances re-read Global Config. */
|
|
3
|
+
const GLOBAL_CONFIG_TTL_MS = 1e4;
|
|
4
|
+
/** Max wait for the first read on a cold start; then the build bundle serves. */
|
|
5
|
+
const COLD_READ_CAP_MS = 20;
|
|
6
|
+
const globalConfigItemKey = (site) => `evolve_bundle_${site}`;
|
|
7
|
+
/**
|
|
8
|
+
* Global Config settings when the app opted in: `store: "global-config"`, or
|
|
9
|
+
* `"auto"` with `EVOLVE_GLOBAL_CONFIG` (connection string) set.
|
|
10
|
+
*/
|
|
11
|
+
function globalConfigSettings(store, env) {
|
|
12
|
+
if (store === "memory") return null;
|
|
13
|
+
const connectionString = env.EVOLVE_GLOBAL_CONFIG;
|
|
14
|
+
if (!connectionString) {
|
|
15
|
+
if (store === "global-config") console.error("[evolve] store: \"global-config\" needs EVOLVE_GLOBAL_CONFIG; using memory");
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
connectionString,
|
|
20
|
+
id: env.EVOLVE_GLOBAL_CONFIG_ID,
|
|
21
|
+
apiToken: env.EVOLVE_VERCEL_API_TOKEN,
|
|
22
|
+
teamId: env.EVOLVE_VERCEL_TEAM_ID
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function defaultReader(connectionString) {
|
|
26
|
+
let client = null;
|
|
27
|
+
return async (key) => {
|
|
28
|
+
client ??= import("@vercel/global-config").then((m) => m.createClient(connectionString));
|
|
29
|
+
return (await client).get(key);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** `"<ver>.<iat>"` of a token, without verifying it (verification is the store's job). */
|
|
33
|
+
function versionOf(token) {
|
|
34
|
+
try {
|
|
35
|
+
const p = JSON.parse(Buffer.from(token.split(".")[1] ?? "", "base64url").toString("utf8"));
|
|
36
|
+
return typeof p.ver === "number" && typeof p.iat === "number" ? p : null;
|
|
37
|
+
} catch {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const newer = (a, b) => {
|
|
42
|
+
const x = versionOf(a);
|
|
43
|
+
const y = versionOf(b);
|
|
44
|
+
if (!x) return b;
|
|
45
|
+
if (!y) return a;
|
|
46
|
+
return x.ver > y.ver || x.ver === y.ver && x.iat >= y.iat ? a : b;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Fetcher for the memory store: reads Global Config every call; also asks the
|
|
50
|
+
* cloud when Global Config is empty or every `cloudEveryMs` (so a missed
|
|
51
|
+
* webhook or a stale item can't freeze the app), and returns the newer token.
|
|
52
|
+
*/
|
|
53
|
+
function createGlobalConfigFetcher(opts) {
|
|
54
|
+
const now = opts.now ?? Date.now;
|
|
55
|
+
const key = globalConfigItemKey(opts.site);
|
|
56
|
+
let lastCloud = -Infinity;
|
|
57
|
+
return async (etag) => {
|
|
58
|
+
let fromConfig = null;
|
|
59
|
+
try {
|
|
60
|
+
const v = await opts.read(key);
|
|
61
|
+
fromConfig = typeof v === "string" && v ? v : null;
|
|
62
|
+
} catch (e) {
|
|
63
|
+
if (!opts.cloud) return {
|
|
64
|
+
status: "error",
|
|
65
|
+
code: "network",
|
|
66
|
+
message: String(e)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
let fromCloud = null;
|
|
70
|
+
if (opts.cloud && (!fromConfig || now() - lastCloud >= opts.cloudEveryMs)) {
|
|
71
|
+
lastCloud = now();
|
|
72
|
+
const r = await opts.cloud(fromConfig ? null : etag);
|
|
73
|
+
if (r.status === "ok") fromCloud = r.token;
|
|
74
|
+
else if (!fromConfig) return r;
|
|
75
|
+
}
|
|
76
|
+
const best = fromConfig && fromCloud ? newer(fromConfig, fromCloud) : fromConfig ?? fromCloud;
|
|
77
|
+
if (!best) return { status: "not_modified" };
|
|
78
|
+
const v = versionOf(best);
|
|
79
|
+
if (v && etag === `"${v.ver}.${v.iat}"`) return { status: "not_modified" };
|
|
80
|
+
return {
|
|
81
|
+
status: "ok",
|
|
82
|
+
token: best,
|
|
83
|
+
etag: null
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Writes the token to the site's item via the Vercel REST API (sync route).
|
|
89
|
+
* Never throws; returns whether the write succeeded.
|
|
90
|
+
*/
|
|
91
|
+
async function writeGlobalConfig(settings, site, token, f = fetch) {
|
|
92
|
+
if (!settings.id || !settings.apiToken) {
|
|
93
|
+
console.error("[evolve] Global Config is read-only here: set EVOLVE_GLOBAL_CONFIG_ID and EVOLVE_VERCEL_API_TOKEN");
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
const url = new URL(`https://api.vercel.com/v1/edge-config/${settings.id}/items`);
|
|
97
|
+
if (settings.teamId) url.searchParams.set("teamId", settings.teamId);
|
|
98
|
+
try {
|
|
99
|
+
const res = await f(url, {
|
|
100
|
+
method: "PATCH",
|
|
101
|
+
headers: {
|
|
102
|
+
authorization: `Bearer ${settings.apiToken}`,
|
|
103
|
+
"content-type": "application/json"
|
|
104
|
+
},
|
|
105
|
+
body: JSON.stringify({ items: [{
|
|
106
|
+
operation: "upsert",
|
|
107
|
+
key: globalConfigItemKey(site),
|
|
108
|
+
value: token
|
|
109
|
+
}] }),
|
|
110
|
+
signal: AbortSignal.timeout(1e4)
|
|
111
|
+
});
|
|
112
|
+
if (!res.ok) {
|
|
113
|
+
const body = await res.text().catch(() => "");
|
|
114
|
+
console.error(`[evolve] Global Config write failed (${res.status})`, body.slice(0, 200));
|
|
115
|
+
}
|
|
116
|
+
return res.ok;
|
|
117
|
+
} catch (e) {
|
|
118
|
+
console.error("[evolve] Global Config write failed", e);
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
export { COLD_READ_CAP_MS, GLOBAL_CONFIG_TTL_MS, createGlobalConfigFetcher, defaultReader, globalConfigItemKey, globalConfigSettings, writeGlobalConfig };
|
package/dist/store/memory.d.ts
CHANGED
|
@@ -8,8 +8,15 @@ export type BundleStore = {
|
|
|
8
8
|
peek(waitUntil?: (p: Promise<unknown>) => void): BundlePayload | null;
|
|
9
9
|
/** Verifies and installs a token (build bundle, disk, sync route). Returns whether it was accepted. */
|
|
10
10
|
load(token: string): boolean;
|
|
11
|
-
/**
|
|
12
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Fetches now (one in flight). Resolves once done. `force`: a fetch already
|
|
13
|
+
* in flight may predate a publish, so wait for it and fetch again.
|
|
14
|
+
*/
|
|
15
|
+
refresh(opts?: {
|
|
16
|
+
force?: boolean;
|
|
17
|
+
}): Promise<void>;
|
|
18
|
+
/** The current bundle without side effects (no refresh; expiry not applied). */
|
|
19
|
+
current(): BundlePayload | null;
|
|
13
20
|
/** Raw token of the current bundle (for persistence). */
|
|
14
21
|
token(): string | null;
|
|
15
22
|
};
|
|
@@ -22,6 +29,8 @@ export type MemoryStoreOptions = {
|
|
|
22
29
|
initialToken?: string | null;
|
|
23
30
|
now?: () => number;
|
|
24
31
|
random?: () => number;
|
|
32
|
+
/** Called with each token accepted after creation (persistence). */
|
|
33
|
+
onAccept?: (token: string) => void;
|
|
25
34
|
};
|
|
26
35
|
/**
|
|
27
36
|
* In-memory bundle store with stale-while-revalidate polling (spec §7.5):
|
package/dist/store/memory.js
CHANGED
|
@@ -16,6 +16,7 @@ function createMemoryStore(opts) {
|
|
|
16
16
|
const schedule = () => {
|
|
17
17
|
nextCheck = now() + opts.pollMs * (.9 + .2 * random());
|
|
18
18
|
};
|
|
19
|
+
let ready = false;
|
|
19
20
|
function load(token) {
|
|
20
21
|
const r = verifyBundle(token, {
|
|
21
22
|
keys: opts.keys,
|
|
@@ -33,11 +34,12 @@ function createMemoryStore(opts) {
|
|
|
33
34
|
current = r.payload;
|
|
34
35
|
currentToken = token;
|
|
35
36
|
etag = `"${r.payload.ver}.${r.payload.iat}"`;
|
|
37
|
+
if (ready) opts.onAccept?.(token);
|
|
36
38
|
return true;
|
|
37
39
|
}
|
|
38
|
-
function refresh() {
|
|
40
|
+
function refresh(o = {}) {
|
|
39
41
|
if (!opts.fetcher) return Promise.resolve();
|
|
40
|
-
if (inflight) return inflight;
|
|
42
|
+
if (inflight) return o.force ? inflight.then(() => refresh()) : inflight;
|
|
41
43
|
schedule();
|
|
42
44
|
inflight = opts.fetcher(etag).then((res) => {
|
|
43
45
|
if (res.status === "ok") load(res.token);
|
|
@@ -48,6 +50,7 @@ function createMemoryStore(opts) {
|
|
|
48
50
|
return inflight;
|
|
49
51
|
}
|
|
50
52
|
if (opts.initialToken) load(opts.initialToken);
|
|
53
|
+
ready = true;
|
|
51
54
|
return {
|
|
52
55
|
peek(waitUntil) {
|
|
53
56
|
if (current && now() >= current.exp * 1e3) {
|
|
@@ -62,6 +65,7 @@ function createMemoryStore(opts) {
|
|
|
62
65
|
},
|
|
63
66
|
load,
|
|
64
67
|
refresh,
|
|
68
|
+
current: () => current,
|
|
65
69
|
token: () => currentToken
|
|
66
70
|
};
|
|
67
71
|
}
|
package/dist/store/runtime.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { GlobalConfigReader } from "./global-config.js";
|
|
1
2
|
import { BundleStore } from "./memory.js";
|
|
2
3
|
import { KeyRing } from "@next-evolve/protocol";
|
|
3
4
|
type Env = Record<string, string | undefined>;
|
|
@@ -7,7 +8,13 @@ export type RuntimeOptions = {
|
|
|
7
8
|
/** Inject a store (tests). */
|
|
8
9
|
store?: BundleStore;
|
|
9
10
|
env?: Env;
|
|
11
|
+
/** Global Config reader (tests). */
|
|
12
|
+
globalConfigReader?: GlobalConfigReader;
|
|
13
|
+
/** Disk cache directory on long-running Node (default: $EVOLVE_CACHE_DIR, else os.tmpdir()). */
|
|
14
|
+
diskDir?: string;
|
|
10
15
|
};
|
|
16
|
+
/** True off serverless hosts: a process that lives across requests (next start, Docker). */
|
|
17
|
+
export declare function isLongRunningNode(env?: Env): boolean;
|
|
11
18
|
/** Default cloud URL (decision D29). Override with EVOLVE_CLOUD_URL. */
|
|
12
19
|
export declare const DEFAULT_CLOUD_URL: string | undefined;
|
|
13
20
|
/**
|
|
@@ -17,7 +24,14 @@ export declare const DEFAULT_CLOUD_URL: string | undefined;
|
|
|
17
24
|
*/
|
|
18
25
|
export declare function getBundleStore(config: {
|
|
19
26
|
pollSeconds?: number;
|
|
27
|
+
store?: "auto" | "memory" | "global-config";
|
|
20
28
|
}, opts?: RuntimeOptions): BundleStore | null;
|
|
29
|
+
/**
|
|
30
|
+
* Global Config hosts, first request of an instance: a promise that resolves
|
|
31
|
+
* after one Global Config read or {@link COLD_READ_CAP_MS}, whichever comes
|
|
32
|
+
* first (spec §7.8). Null when there's nothing to wait for.
|
|
33
|
+
*/
|
|
34
|
+
export declare function coldStart(store: BundleStore): Promise<void> | null;
|
|
21
35
|
/** This app's site id (from EVOLVE_SECRET_KEY) and trusted public keys. Cached; null without a valid key. */
|
|
22
36
|
export declare function getSiteIdentity(opts?: {
|
|
23
37
|
env?: Env;
|
package/dist/store/runtime.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { trustedKeys } from "../core/keys.js";
|
|
2
|
+
import { defaultDiskDir, diskPath, readDisk, writeDisk } from "./disk.js";
|
|
2
3
|
import { fetchBundle } from "./fetch.js";
|
|
4
|
+
import { GLOBAL_CONFIG_TTL_MS, createGlobalConfigFetcher, defaultReader, globalConfigSettings } from "./global-config.js";
|
|
3
5
|
import { createMemoryStore } from "./memory.js";
|
|
4
6
|
import { parseSecretKey } from "@next-evolve/protocol";
|
|
5
7
|
// src/store/runtime.ts
|
|
8
|
+
/** True off serverless hosts: a process that lives across requests (next start, Docker). */
|
|
9
|
+
function isLongRunningNode(env = process.env) {
|
|
10
|
+
return !env.VERCEL && !env.AWS_LAMBDA_FUNCTION_NAME && !env.NETLIFY;
|
|
11
|
+
}
|
|
6
12
|
/** Default cloud URL (decision D29). Override with EVOLVE_CLOUD_URL. */
|
|
7
13
|
const DEFAULT_CLOUD_URL = "https://api.evolveab.com";
|
|
8
14
|
const REGISTRY = Symbol.for("next-evolve.stores");
|
|
@@ -29,20 +35,46 @@ function getBundleStore(config, opts = {}) {
|
|
|
29
35
|
return existing;
|
|
30
36
|
}
|
|
31
37
|
const cloudUrl = env.EVOLVE_CLOUD_URL ?? "https://api.evolveab.com";
|
|
38
|
+
const disk = isLongRunningNode(env) ? diskPath(opts.diskDir ?? env.EVOLVE_CACHE_DIR ?? defaultDiskDir(), site) : null;
|
|
39
|
+
const pollMs = (config.pollSeconds ?? (env.NODE_ENV === "production" ? 60 : 5)) * 1e3;
|
|
40
|
+
const cloud = cloudUrl ? (etag) => fetchBundle({
|
|
41
|
+
cloudUrl,
|
|
42
|
+
secretKey,
|
|
43
|
+
etag
|
|
44
|
+
}) : void 0;
|
|
45
|
+
const gc = globalConfigSettings(config.store, env);
|
|
32
46
|
const store = createMemoryStore({
|
|
33
47
|
site,
|
|
34
48
|
keys: trustedKeys(env),
|
|
35
|
-
pollMs:
|
|
49
|
+
pollMs: gc ? Math.min(pollMs, GLOBAL_CONFIG_TTL_MS) : pollMs,
|
|
36
50
|
initialToken: opts.buildBundle ?? null,
|
|
37
|
-
fetcher:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
51
|
+
fetcher: gc ? createGlobalConfigFetcher({
|
|
52
|
+
site,
|
|
53
|
+
read: opts.globalConfigReader ?? defaultReader(gc.connectionString),
|
|
54
|
+
cloud,
|
|
55
|
+
cloudEveryMs: pollMs
|
|
56
|
+
}) : cloud,
|
|
57
|
+
...disk ? { onAccept: (token) => writeDisk(disk, token) } : {}
|
|
42
58
|
});
|
|
59
|
+
if (disk) {
|
|
60
|
+
const cached = readDisk(disk);
|
|
61
|
+
if (cached && cached !== store.token()) store.load(cached);
|
|
62
|
+
}
|
|
43
63
|
reg.set(site, store);
|
|
64
|
+
if (gc) coldReads.set(store, true);
|
|
44
65
|
return store;
|
|
45
66
|
}
|
|
67
|
+
const coldReads = /* @__PURE__ */ new WeakMap();
|
|
68
|
+
/**
|
|
69
|
+
* Global Config hosts, first request of an instance: a promise that resolves
|
|
70
|
+
* after one Global Config read or {@link COLD_READ_CAP_MS}, whichever comes
|
|
71
|
+
* first (spec §7.8). Null when there's nothing to wait for.
|
|
72
|
+
*/
|
|
73
|
+
function coldStart(store) {
|
|
74
|
+
if (!coldReads.get(store)) return null;
|
|
75
|
+
coldReads.delete(store);
|
|
76
|
+
return Promise.race([store.refresh(), new Promise((r) => setTimeout(r, 20))]);
|
|
77
|
+
}
|
|
46
78
|
const identities = /* @__PURE__ */ new Map();
|
|
47
79
|
/** This app's site id (from EVOLVE_SECRET_KEY) and trusted public keys. Cached; null without a valid key. */
|
|
48
80
|
function getSiteIdentity(opts = {}) {
|
|
@@ -66,4 +98,4 @@ function getSiteIdentity(opts = {}) {
|
|
|
66
98
|
function resetBundleStores() {
|
|
67
99
|
registry().clear();
|
|
68
100
|
}
|
|
69
|
-
export { DEFAULT_CLOUD_URL, getBundleStore, getSiteIdentity, resetBundleStores };
|
|
101
|
+
export { DEFAULT_CLOUD_URL, coldStart, getBundleStore, getSiteIdentity, isLongRunningNode, resetBundleStores };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "next-evolve",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Self-improving Next.js sites: server-side variants with no flicker, measured in your own Postgres.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"./package.json": "./package.json"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
+
"@vercel/global-config": "1.5.1",
|
|
40
41
|
"isbot": "5.2.2",
|
|
41
42
|
"postgres": "3.4.9",
|
|
42
43
|
"server-only": "^0.0.1",
|