@orkify/cli 1.0.0-beta.5 → 1.0.0-beta.6
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 +10 -5
- package/package.json +8 -31
- package/packages/cache/README.md +0 -114
- package/packages/cache/dist/CacheClient.d.ts +0 -26
- package/packages/cache/dist/CacheClient.d.ts.map +0 -1
- package/packages/cache/dist/CacheClient.js +0 -174
- package/packages/cache/dist/CacheClient.js.map +0 -1
- package/packages/cache/dist/CacheFileStore.d.ts +0 -45
- package/packages/cache/dist/CacheFileStore.d.ts.map +0 -1
- package/packages/cache/dist/CacheFileStore.js +0 -446
- package/packages/cache/dist/CacheFileStore.js.map +0 -1
- package/packages/cache/dist/CachePersistence.d.ts +0 -9
- package/packages/cache/dist/CachePersistence.d.ts.map +0 -1
- package/packages/cache/dist/CachePersistence.js +0 -67
- package/packages/cache/dist/CachePersistence.js.map +0 -1
- package/packages/cache/dist/CachePrimary.d.ts +0 -25
- package/packages/cache/dist/CachePrimary.d.ts.map +0 -1
- package/packages/cache/dist/CachePrimary.js +0 -155
- package/packages/cache/dist/CachePrimary.js.map +0 -1
- package/packages/cache/dist/CacheStore.d.ts +0 -50
- package/packages/cache/dist/CacheStore.d.ts.map +0 -1
- package/packages/cache/dist/CacheStore.js +0 -271
- package/packages/cache/dist/CacheStore.js.map +0 -1
- package/packages/cache/dist/constants.d.ts +0 -6
- package/packages/cache/dist/constants.d.ts.map +0 -1
- package/packages/cache/dist/constants.js +0 -9
- package/packages/cache/dist/constants.js.map +0 -1
- package/packages/cache/dist/index.d.ts +0 -16
- package/packages/cache/dist/index.d.ts.map +0 -1
- package/packages/cache/dist/index.js +0 -86
- package/packages/cache/dist/index.js.map +0 -1
- package/packages/cache/dist/serialize.d.ts +0 -9
- package/packages/cache/dist/serialize.d.ts.map +0 -1
- package/packages/cache/dist/serialize.js +0 -40
- package/packages/cache/dist/serialize.js.map +0 -1
- package/packages/cache/dist/types.d.ts +0 -123
- package/packages/cache/dist/types.d.ts.map +0 -1
- package/packages/cache/dist/types.js +0 -2
- package/packages/cache/dist/types.js.map +0 -1
- package/packages/cache/package.json +0 -27
- package/packages/cache/src/CacheClient.ts +0 -227
- package/packages/cache/src/CacheFileStore.ts +0 -528
- package/packages/cache/src/CachePersistence.ts +0 -89
- package/packages/cache/src/CachePrimary.ts +0 -172
- package/packages/cache/src/CacheStore.ts +0 -308
- package/packages/cache/src/constants.ts +0 -10
- package/packages/cache/src/index.ts +0 -100
- package/packages/cache/src/serialize.ts +0 -49
- package/packages/cache/src/types.ts +0 -156
- package/packages/cache/tsconfig.json +0 -18
- package/packages/cache/tsconfig.tsbuildinfo +0 -1
- package/packages/next/README.md +0 -166
- package/packages/next/dist/error-capture.d.ts +0 -34
- package/packages/next/dist/error-capture.d.ts.map +0 -1
- package/packages/next/dist/error-capture.js +0 -130
- package/packages/next/dist/error-capture.js.map +0 -1
- package/packages/next/dist/error-handler.d.ts +0 -10
- package/packages/next/dist/error-handler.d.ts.map +0 -1
- package/packages/next/dist/error-handler.js +0 -186
- package/packages/next/dist/error-handler.js.map +0 -1
- package/packages/next/dist/isr-cache.d.ts +0 -9
- package/packages/next/dist/isr-cache.d.ts.map +0 -1
- package/packages/next/dist/isr-cache.js +0 -86
- package/packages/next/dist/isr-cache.js.map +0 -1
- package/packages/next/dist/stream.d.ts +0 -5
- package/packages/next/dist/stream.d.ts.map +0 -1
- package/packages/next/dist/stream.js +0 -22
- package/packages/next/dist/stream.js.map +0 -1
- package/packages/next/dist/types.d.ts +0 -33
- package/packages/next/dist/types.d.ts.map +0 -1
- package/packages/next/dist/types.js +0 -6
- package/packages/next/dist/types.js.map +0 -1
- package/packages/next/dist/use-cache.d.ts +0 -4
- package/packages/next/dist/use-cache.d.ts.map +0 -1
- package/packages/next/dist/use-cache.js +0 -86
- package/packages/next/dist/use-cache.js.map +0 -1
- package/packages/next/dist/utils.d.ts +0 -32
- package/packages/next/dist/utils.d.ts.map +0 -1
- package/packages/next/dist/utils.js +0 -88
- package/packages/next/dist/utils.js.map +0 -1
- package/packages/next/package.json +0 -52
- package/packages/next/src/error-capture.ts +0 -177
- package/packages/next/src/error-handler.ts +0 -221
- package/packages/next/src/isr-cache.ts +0 -100
- package/packages/next/src/stream.ts +0 -23
- package/packages/next/src/types.ts +0 -33
- package/packages/next/src/use-cache.ts +0 -99
- package/packages/next/src/utils.ts +0 -102
- package/packages/next/tsconfig.json +0 -19
- package/packages/next/tsconfig.tsbuildinfo +0 -1
|
@@ -1,186 +0,0 @@
|
|
|
1
|
-
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { extractContext, parseBrowserFrames } from './utils.js';
|
|
4
|
-
// ── Rate Limiter ────────────────────────────────────────────────────────
|
|
5
|
-
const MAX_ERRORS_PER_WINDOW = 10;
|
|
6
|
-
const WINDOW_MS = 10_000;
|
|
7
|
-
const rateLimits = new Map();
|
|
8
|
-
/** Periodic cleanup to prevent unbounded Map growth. */
|
|
9
|
-
let cleanupTimer = null;
|
|
10
|
-
function ensureCleanupTimer() {
|
|
11
|
-
if (cleanupTimer)
|
|
12
|
-
return;
|
|
13
|
-
cleanupTimer = setInterval(() => {
|
|
14
|
-
const now = Date.now();
|
|
15
|
-
for (const [key, bucket] of rateLimits) {
|
|
16
|
-
if (bucket.resetAt <= now)
|
|
17
|
-
rateLimits.delete(key);
|
|
18
|
-
}
|
|
19
|
-
if (rateLimits.size === 0 && cleanupTimer) {
|
|
20
|
-
clearInterval(cleanupTimer);
|
|
21
|
-
cleanupTimer = null;
|
|
22
|
-
}
|
|
23
|
-
}, 30_000);
|
|
24
|
-
cleanupTimer.unref();
|
|
25
|
-
}
|
|
26
|
-
function isRateLimited(ip) {
|
|
27
|
-
const now = Date.now();
|
|
28
|
-
const bucket = rateLimits.get(ip);
|
|
29
|
-
if (!bucket || bucket.resetAt <= now) {
|
|
30
|
-
rateLimits.set(ip, { count: 1, resetAt: now + WINDOW_MS });
|
|
31
|
-
ensureCleanupTimer();
|
|
32
|
-
return false;
|
|
33
|
-
}
|
|
34
|
-
bucket.count++;
|
|
35
|
-
return bucket.count > MAX_ERRORS_PER_WINDOW;
|
|
36
|
-
}
|
|
37
|
-
// ── Validation ──────────────────────────────────────────────────────────
|
|
38
|
-
const MAX_BODY_SIZE = 65_536; // 64 KB
|
|
39
|
-
const MAX_STACK_LINES = 100;
|
|
40
|
-
const browserErrorSchema = z.object({
|
|
41
|
-
name: z.string().max(256),
|
|
42
|
-
message: z.string().max(4096),
|
|
43
|
-
stack: z.string().max(32_768),
|
|
44
|
-
errorType: z.enum(['browser:error', 'browser:unhandledRejection']),
|
|
45
|
-
url: z.string().max(2048),
|
|
46
|
-
userAgent: z.string().max(512),
|
|
47
|
-
timestamp: z.number(),
|
|
48
|
-
});
|
|
49
|
-
function buildSourceContext(frames) {
|
|
50
|
-
const result = [];
|
|
51
|
-
for (const frame of frames) {
|
|
52
|
-
if (!existsSync(frame.file))
|
|
53
|
-
continue;
|
|
54
|
-
try {
|
|
55
|
-
const source = readFileSync(frame.file, 'utf8');
|
|
56
|
-
const context = extractContext(source, frame.line);
|
|
57
|
-
if (!context)
|
|
58
|
-
continue;
|
|
59
|
-
result.push({
|
|
60
|
-
file: frame.file,
|
|
61
|
-
line: frame.line,
|
|
62
|
-
column: frame.column,
|
|
63
|
-
pre: context.pre,
|
|
64
|
-
target: context.target,
|
|
65
|
-
post: context.post,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
catch {
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return result;
|
|
73
|
-
}
|
|
74
|
-
// ── Request Handler ─────────────────────────────────────────────────────
|
|
75
|
-
function getClientIp(request) {
|
|
76
|
-
// Cloudflare: most reliable, cannot be spoofed by the client
|
|
77
|
-
const cfIp = request.headers.get('cf-connecting-ip');
|
|
78
|
-
if (cfIp)
|
|
79
|
-
return cfIp;
|
|
80
|
-
// Standard proxy headers
|
|
81
|
-
const xff = request.headers.get('x-forwarded-for');
|
|
82
|
-
if (xff)
|
|
83
|
-
return xff.split(',')[0].trim();
|
|
84
|
-
const realIp = request.headers.get('x-real-ip');
|
|
85
|
-
if (realIp)
|
|
86
|
-
return realIp;
|
|
87
|
-
return '127.0.0.1';
|
|
88
|
-
}
|
|
89
|
-
/**
|
|
90
|
-
* Next.js API route handler for browser error reporting.
|
|
91
|
-
*
|
|
92
|
-
* Create `app/orkify/errors/route.ts`:
|
|
93
|
-
* ```ts
|
|
94
|
-
* export { POST } from '@orkify/next/error-handler';
|
|
95
|
-
* ```
|
|
96
|
-
*/
|
|
97
|
-
export async function POST(request) {
|
|
98
|
-
try {
|
|
99
|
-
// 1. Validate origin — browsers always send Origin on POST requests.
|
|
100
|
-
// This blocks cross-origin abuse and non-browser clients (curl/bots).
|
|
101
|
-
// Behind reverse proxies (nginx, Cloudflare), Host may be internal
|
|
102
|
-
// while Origin is public. X-Forwarded-Host carries the original Host.
|
|
103
|
-
const origin = request.headers.get('origin');
|
|
104
|
-
if (!origin) {
|
|
105
|
-
return Response.json({ ok: false }, { status: 403 });
|
|
106
|
-
}
|
|
107
|
-
const effectiveHost = request.headers.get('x-forwarded-host') || request.headers.get('host');
|
|
108
|
-
if (effectiveHost) {
|
|
109
|
-
try {
|
|
110
|
-
const originHost = new URL(origin).host;
|
|
111
|
-
if (originHost !== effectiveHost) {
|
|
112
|
-
return Response.json({ ok: false }, { status: 403 });
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
catch {
|
|
116
|
-
return Response.json({ ok: false }, { status: 403 });
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
// 2. Check content length
|
|
120
|
-
const contentLength = request.headers.get('content-length');
|
|
121
|
-
if (contentLength && parseInt(contentLength, 10) > MAX_BODY_SIZE) {
|
|
122
|
-
return Response.json({ ok: false }, { status: 413 });
|
|
123
|
-
}
|
|
124
|
-
// 3. Rate limit
|
|
125
|
-
const ip = getClientIp(request);
|
|
126
|
-
if (isRateLimited(ip)) {
|
|
127
|
-
return Response.json({ ok: false }, { status: 429 });
|
|
128
|
-
}
|
|
129
|
-
// 4. Parse and validate body
|
|
130
|
-
const raw = await request.text();
|
|
131
|
-
if (raw.length > MAX_BODY_SIZE) {
|
|
132
|
-
return Response.json({ ok: false }, { status: 413 });
|
|
133
|
-
}
|
|
134
|
-
let body;
|
|
135
|
-
try {
|
|
136
|
-
body = JSON.parse(raw);
|
|
137
|
-
}
|
|
138
|
-
catch {
|
|
139
|
-
return Response.json({ ok: false }, { status: 400 });
|
|
140
|
-
}
|
|
141
|
-
const parsed = browserErrorSchema.safeParse(body);
|
|
142
|
-
if (!parsed.success) {
|
|
143
|
-
return Response.json({ ok: false }, { status: 400 });
|
|
144
|
-
}
|
|
145
|
-
const data = parsed.data;
|
|
146
|
-
// 5. Truncate stack to max lines
|
|
147
|
-
const stackLines = data.stack.split('\n');
|
|
148
|
-
const truncatedStack = stackLines.length > MAX_STACK_LINES
|
|
149
|
-
? stackLines.slice(0, MAX_STACK_LINES).join('\n')
|
|
150
|
-
: data.stack;
|
|
151
|
-
// 6. Parse browser stack → frames, map URLs to file paths
|
|
152
|
-
const cwd = process.cwd();
|
|
153
|
-
const frames = parseBrowserFrames(truncatedStack, cwd);
|
|
154
|
-
// 7. Build source context from bundled files on disk
|
|
155
|
-
const sourceContext = frames.length > 0 ? buildSourceContext(frames) : null;
|
|
156
|
-
const topFrame = frames[0] ?? null;
|
|
157
|
-
// 8. Relay to daemon via IPC
|
|
158
|
-
if (typeof process.send === 'function') {
|
|
159
|
-
process.send({
|
|
160
|
-
__orkify: true,
|
|
161
|
-
type: 'error',
|
|
162
|
-
data: {
|
|
163
|
-
errorType: data.errorType,
|
|
164
|
-
name: data.name,
|
|
165
|
-
message: data.message,
|
|
166
|
-
stack: truncatedStack,
|
|
167
|
-
fingerprint: '', // Daemon recomputes this
|
|
168
|
-
sourceContext: sourceContext && sourceContext.length > 0 ? sourceContext : null,
|
|
169
|
-
topFrame,
|
|
170
|
-
diagnostics: null,
|
|
171
|
-
timestamp: data.timestamp,
|
|
172
|
-
nodeVersion: '',
|
|
173
|
-
pid: 0,
|
|
174
|
-
url: data.url,
|
|
175
|
-
userAgent: data.userAgent,
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
return Response.json({ ok: true });
|
|
180
|
-
}
|
|
181
|
-
catch {
|
|
182
|
-
// Never crash the app for error reporting
|
|
183
|
-
return Response.json({ ok: true });
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
//# sourceMappingURL=error-handler.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../src/error-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export default class OrkifyCacheHandler {
|
|
2
|
-
get(key: string): Promise<null | unknown>;
|
|
3
|
-
set(key: string, data: unknown, ctx?: {
|
|
4
|
-
tags?: string[];
|
|
5
|
-
}): Promise<void>;
|
|
6
|
-
revalidateTag(tag: string | string[]): Promise<void>;
|
|
7
|
-
resetRequestCache(): void;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=isr-cache.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isr-cache.d.ts","sourceRoot":"","sources":["../src/isr-cache.ts"],"names":[],"mappings":"AAsDA,MAAM,CAAC,OAAO,OAAO,kBAAkB;IAC/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC;IASzC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyBzE,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAO1D,iBAAiB,IAAI,IAAI;CAG1B"}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { cache } from '@orkify/cache';
|
|
2
|
-
/**
|
|
3
|
-
* ISR / route cache handler for Next.js (`cacheHandler` config).
|
|
4
|
-
* Next.js instantiates this with `new`, so it must be a class.
|
|
5
|
-
*
|
|
6
|
-
* Next.js expects `get()` to return `{ value, lastModified }` (the
|
|
7
|
-
* `CacheHandlerValue` interface), so we wrap/unwrap around the raw
|
|
8
|
-
* `IncrementalCacheValue` when storing in orkify/cache.
|
|
9
|
-
*
|
|
10
|
-
* During `next build`, this handler is a no-op — data stored in-memory
|
|
11
|
-
* would be lost when the build process exits, causing invariant errors
|
|
12
|
-
* at runtime when Next.js expects cached pages that no longer exist.
|
|
13
|
-
* Pre-rendered pages are still served from disk (`.next/server/app/`).
|
|
14
|
-
*
|
|
15
|
-
* Headers objects (used by APP_ROUTE responses) don't survive V8
|
|
16
|
-
* structured clone (IPC in cluster mode). We convert them to plain
|
|
17
|
-
* objects on set so they work with both IPC and bracket-notation
|
|
18
|
-
* access in Next.js internals.
|
|
19
|
-
*
|
|
20
|
-
* Cache tags are extracted from the `x-next-cache-tags` header (set by
|
|
21
|
-
* Next.js for APP_PAGE/APP_ROUTE) and registered in orkify's tag index
|
|
22
|
-
* so `revalidateTag()` → `cache.invalidateTag()` can find entries.
|
|
23
|
-
*/
|
|
24
|
-
const IS_BUILD = process.env.NEXT_PHASE === 'phase-production-build';
|
|
25
|
-
const NEXT_CACHE_TAGS_HEADER = 'x-next-cache-tags';
|
|
26
|
-
/** Convert Headers to a plain object. Non-Headers pass through. */
|
|
27
|
-
function headersToPlainObject(headers) {
|
|
28
|
-
if (!headers)
|
|
29
|
-
return undefined;
|
|
30
|
-
if (headers instanceof Headers) {
|
|
31
|
-
return Object.fromEntries([...headers.entries()]);
|
|
32
|
-
}
|
|
33
|
-
if (Array.isArray(headers)) {
|
|
34
|
-
// entries array from a previous version — normalize to plain object
|
|
35
|
-
return Object.fromEntries(headers);
|
|
36
|
-
}
|
|
37
|
-
return headers;
|
|
38
|
-
}
|
|
39
|
-
/** Extract cache tags from the x-next-cache-tags header value. */
|
|
40
|
-
function extractTags(headers) {
|
|
41
|
-
const tagHeader = headers?.[NEXT_CACHE_TAGS_HEADER];
|
|
42
|
-
if (typeof tagHeader === 'string' && tagHeader.length > 0) {
|
|
43
|
-
return tagHeader.split(',');
|
|
44
|
-
}
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
export default class OrkifyCacheHandler {
|
|
48
|
-
async get(key) {
|
|
49
|
-
if (IS_BUILD)
|
|
50
|
-
return null;
|
|
51
|
-
const stored = await cache.getAsync(key);
|
|
52
|
-
if (!stored)
|
|
53
|
-
return null;
|
|
54
|
-
return stored;
|
|
55
|
-
}
|
|
56
|
-
async set(key, data, ctx) {
|
|
57
|
-
if (IS_BUILD)
|
|
58
|
-
return;
|
|
59
|
-
let value = data;
|
|
60
|
-
// Normalize Headers objects to plain objects for IPC and bracket-notation access
|
|
61
|
-
if (value && 'headers' in value) {
|
|
62
|
-
const plainHeaders = headersToPlainObject(value.headers);
|
|
63
|
-
if (plainHeaders !== value.headers) {
|
|
64
|
-
value = { ...value, headers: plainHeaders };
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
// Gather tags: merge explicit ctx.tags with x-next-cache-tags header (deduplicated)
|
|
68
|
-
const headerTags = value ? extractTags(value.headers) : undefined;
|
|
69
|
-
const mergedTags = ctx?.tags && headerTags
|
|
70
|
-
? [...new Set([...ctx.tags, ...headerTags])]
|
|
71
|
-
: (ctx?.tags ?? headerTags);
|
|
72
|
-
const tags = mergedTags && mergedTags.length > 0 ? mergedTags : undefined;
|
|
73
|
-
const entry = { value, lastModified: Date.now() };
|
|
74
|
-
cache.set(key, entry, tags ? { tags } : undefined);
|
|
75
|
-
}
|
|
76
|
-
async revalidateTag(tag) {
|
|
77
|
-
const tags = Array.isArray(tag) ? tag : [tag];
|
|
78
|
-
for (const t of tags) {
|
|
79
|
-
cache.invalidateTag(t);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
resetRequestCache() {
|
|
83
|
-
// No-op — shared cache, not per-request
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
//# sourceMappingURL=isr-cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"isr-cache.js","sourceRoot":"","sources":["../src/isr-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
/** Consume a ReadableStream into a single Buffer. */
|
|
2
|
-
export declare function streamToBuffer(stream: ReadableStream<Uint8Array>): Promise<Buffer>;
|
|
3
|
-
/** Create a single-chunk ReadableStream from a Buffer. */
|
|
4
|
-
export declare function bufferToStream(buffer: Buffer): ReadableStream<Uint8Array>;
|
|
5
|
-
//# sourceMappingURL=stream.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream.d.ts","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,wBAAsB,cAAc,CAAC,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAWxF;AAED,0DAA0D;AAC1D,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAOzE"}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
/** Consume a ReadableStream into a single Buffer. */
|
|
2
|
-
export async function streamToBuffer(stream) {
|
|
3
|
-
const chunks = [];
|
|
4
|
-
const reader = stream.getReader();
|
|
5
|
-
for (;;) {
|
|
6
|
-
const { done, value } = await reader.read();
|
|
7
|
-
if (done)
|
|
8
|
-
break;
|
|
9
|
-
chunks.push(value);
|
|
10
|
-
}
|
|
11
|
-
return Buffer.concat(chunks);
|
|
12
|
-
}
|
|
13
|
-
/** Create a single-chunk ReadableStream from a Buffer. */
|
|
14
|
-
export function bufferToStream(buffer) {
|
|
15
|
-
return new ReadableStream({
|
|
16
|
-
start(controller) {
|
|
17
|
-
controller.enqueue(new Uint8Array(buffer));
|
|
18
|
-
controller.close();
|
|
19
|
-
},
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
//# sourceMappingURL=stream.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../src/stream.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAkC;IACrE,MAAM,MAAM,GAAiB,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;IAElC,SAAS,CAAC;QACR,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI;YAAE,MAAM;QAChB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,IAAI,cAAc,CAAC;QACxB,KAAK,CAAC,UAAU;YACd,UAAU,CAAC,OAAO,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3C,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Next.js cache handler interfaces, mirrored here so orkify doesn't
|
|
3
|
-
* depend on `next` as a package dependency.
|
|
4
|
-
*/
|
|
5
|
-
/** What Next.js passes to / expects from the 'use cache' handler. */
|
|
6
|
-
export interface NextCacheEntry {
|
|
7
|
-
expire: number;
|
|
8
|
-
revalidate: number;
|
|
9
|
-
stale: number;
|
|
10
|
-
tags: string[];
|
|
11
|
-
timestamp: number;
|
|
12
|
-
value: ReadableStream<Uint8Array>;
|
|
13
|
-
}
|
|
14
|
-
/** 'use cache' handler — 5 methods. */
|
|
15
|
-
export interface NextCacheHandler {
|
|
16
|
-
get(cacheKey: string, softTags: string[]): Promise<NextCacheEntry | undefined>;
|
|
17
|
-
getExpiration(tags: string[]): Promise<number>;
|
|
18
|
-
refreshTags(): Promise<void>;
|
|
19
|
-
set(cacheKey: string, pendingEntry: Promise<NextCacheEntry>): Promise<void>;
|
|
20
|
-
updateTags(tags: string[], durations?: {
|
|
21
|
-
expire?: number;
|
|
22
|
-
}): Promise<void>;
|
|
23
|
-
}
|
|
24
|
-
/** What we actually store in orkify/cache (Buffer instead of stream). */
|
|
25
|
-
export interface StoredCacheEntry {
|
|
26
|
-
buffer: Buffer;
|
|
27
|
-
expire: number;
|
|
28
|
-
revalidate: number;
|
|
29
|
-
stale: number;
|
|
30
|
-
tags: string[];
|
|
31
|
-
timestamp: number;
|
|
32
|
-
}
|
|
33
|
-
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,qEAAqE;AACrE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,cAAc,CAAC,UAAU,CAAC,CAAC;CACnC;AAED,uCAAuC;AACvC,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IAC/E,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/C,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5E;AAED,yEAAyE;AACzE,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-cache.d.ts","sourceRoot":"","sources":["../src/use-cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,gBAAgB,EAAoB,MAAM,YAAY,CAAC;AAOrF,QAAA,MAAM,OAAO,EAAE,gBAyFd,CAAC;AAEF,eAAe,OAAO,CAAC"}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { cache } from '@orkify/cache';
|
|
2
|
-
import { bufferToStream, streamToBuffer } from './stream.js';
|
|
3
|
-
const REVALIDATING_PREFIX = '__revalidating:';
|
|
4
|
-
const REVALIDATING_TTL = 30; // seconds
|
|
5
|
-
const handler = {
|
|
6
|
-
async get(cacheKey, softTags) {
|
|
7
|
-
const stored = await cache.getAsync(cacheKey);
|
|
8
|
-
if (!stored)
|
|
9
|
-
return undefined;
|
|
10
|
-
const now = Date.now();
|
|
11
|
-
// Hard expiration — not coalesced (entry is genuinely expired)
|
|
12
|
-
if (stored.expire > 0 && now > stored.timestamp + stored.expire * 1000) {
|
|
13
|
-
cache.delete(cacheKey);
|
|
14
|
-
return undefined;
|
|
15
|
-
}
|
|
16
|
-
// Revalidation window — coalesce concurrent revalidations
|
|
17
|
-
if (stored.revalidate > 0 && now > stored.timestamp + stored.revalidate * 1000) {
|
|
18
|
-
if (cache.has(REVALIDATING_PREFIX + cacheKey)) {
|
|
19
|
-
// Another worker is already revalidating — serve stale content
|
|
20
|
-
return {
|
|
21
|
-
value: bufferToStream(stored.buffer),
|
|
22
|
-
tags: stored.tags,
|
|
23
|
-
stale: stored.stale,
|
|
24
|
-
timestamp: stored.timestamp,
|
|
25
|
-
expire: stored.expire,
|
|
26
|
-
revalidate: stored.revalidate,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
// Claim the revalidation lock
|
|
30
|
-
cache.set(REVALIDATING_PREFIX + cacheKey, true, { ttl: REVALIDATING_TTL });
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
33
|
-
// Tag invalidation — not coalesced (explicit invalidation should always miss)
|
|
34
|
-
// Check both explicit tags (from cacheTag()) and soft tags (implicit route tags)
|
|
35
|
-
if (stored.tags.length > 0 && cache.getTagExpiration(stored.tags) > stored.timestamp) {
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
38
|
-
if (softTags.length > 0 && cache.getTagExpiration(softTags) > stored.timestamp) {
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
return {
|
|
42
|
-
value: bufferToStream(stored.buffer),
|
|
43
|
-
tags: stored.tags,
|
|
44
|
-
stale: stored.stale,
|
|
45
|
-
timestamp: stored.timestamp,
|
|
46
|
-
expire: stored.expire,
|
|
47
|
-
revalidate: stored.revalidate,
|
|
48
|
-
};
|
|
49
|
-
},
|
|
50
|
-
async set(cacheKey, pendingEntry) {
|
|
51
|
-
const entry = await pendingEntry;
|
|
52
|
-
const buffer = await streamToBuffer(entry.value);
|
|
53
|
-
const stored = {
|
|
54
|
-
buffer,
|
|
55
|
-
tags: entry.tags,
|
|
56
|
-
stale: entry.stale,
|
|
57
|
-
timestamp: entry.timestamp,
|
|
58
|
-
expire: entry.expire,
|
|
59
|
-
revalidate: entry.revalidate,
|
|
60
|
-
};
|
|
61
|
-
cache.set(cacheKey, stored, {
|
|
62
|
-
tags: entry.tags,
|
|
63
|
-
ttl: entry.expire > 0 ? entry.expire : undefined,
|
|
64
|
-
});
|
|
65
|
-
// Clear the revalidation lock now that fresh content is stored
|
|
66
|
-
cache.delete(REVALIDATING_PREFIX + cacheKey);
|
|
67
|
-
},
|
|
68
|
-
async refreshTags() {
|
|
69
|
-
// No-op — IPC keeps workers in sync
|
|
70
|
-
},
|
|
71
|
-
async getExpiration(tags) {
|
|
72
|
-
return cache.getTagExpiration(tags);
|
|
73
|
-
},
|
|
74
|
-
async updateTags(tags, durations) {
|
|
75
|
-
for (const tag of tags) {
|
|
76
|
-
if (durations?.expire !== undefined) {
|
|
77
|
-
cache.updateTagTimestamp(tag, Date.now() + durations.expire * 1000);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
cache.invalidateTag(tag);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
export default handler;
|
|
86
|
-
//# sourceMappingURL=use-cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"use-cache.js","sourceRoot":"","sources":["../src/use-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser stack frame parsing — extracted from probe/parse-frames.ts.
|
|
3
|
-
* Only the browser-specific logic needed by the error handler.
|
|
4
|
-
*/
|
|
5
|
-
export interface StackFrame {
|
|
6
|
-
file: string;
|
|
7
|
-
line: number;
|
|
8
|
-
column: number;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Map a browser URL to a local file path.
|
|
12
|
-
* Strips the origin, maps Next.js `/_next/static/` to `.next/static/`,
|
|
13
|
-
* and resolves the path against the working directory.
|
|
14
|
-
* Returns null for unmappable URLs.
|
|
15
|
-
*/
|
|
16
|
-
export declare function mapBrowserUrlToPath(url: string, cwd: string): null | string;
|
|
17
|
-
/**
|
|
18
|
-
* Parse stack frames from a browser Error.stack string.
|
|
19
|
-
* Expects V8 format (Chrome stacks or pre-normalized Firefox/Safari stacks).
|
|
20
|
-
* Maps http/https URLs to local file paths using Next.js conventions.
|
|
21
|
-
*/
|
|
22
|
-
export declare function parseBrowserFrames(stack: string, cwd: string): StackFrame[];
|
|
23
|
-
/**
|
|
24
|
-
* Extract source context lines around a target line number.
|
|
25
|
-
* Returns 5 lines before, the target line, and 5 lines after.
|
|
26
|
-
*/
|
|
27
|
-
export declare function extractContext(source: string, line: number): null | {
|
|
28
|
-
pre: string[];
|
|
29
|
-
target: string;
|
|
30
|
-
post: string[];
|
|
31
|
-
};
|
|
32
|
-
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAQD;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAmB3E;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,UAAU,EAAE,CA6B3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GACX,IAAI,GAAG;IAAE,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAY1D"}
|
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Browser stack frame parsing — extracted from probe/parse-frames.ts.
|
|
3
|
-
* Only the browser-specific logic needed by the error handler.
|
|
4
|
-
*/
|
|
5
|
-
import { resolve } from 'node:path';
|
|
6
|
-
const STACK_LINE_RE = /at\s+(?:.*?\s+)?\(?(.+?):(\d+):(\d+)\)?$/;
|
|
7
|
-
/** URL schemes that indicate browser internals (skipped). */
|
|
8
|
-
const BROWSER_INTERNAL_RE = /^(?:chrome-extension|moz-extension|safari-extension|about|blob|data):/i;
|
|
9
|
-
/**
|
|
10
|
-
* Map a browser URL to a local file path.
|
|
11
|
-
* Strips the origin, maps Next.js `/_next/static/` to `.next/static/`,
|
|
12
|
-
* and resolves the path against the working directory.
|
|
13
|
-
* Returns null for unmappable URLs.
|
|
14
|
-
*/
|
|
15
|
-
export function mapBrowserUrlToPath(url, cwd) {
|
|
16
|
-
if (BROWSER_INTERNAL_RE.test(url))
|
|
17
|
-
return null;
|
|
18
|
-
let pathname;
|
|
19
|
-
try {
|
|
20
|
-
pathname = new URL(url).pathname;
|
|
21
|
-
}
|
|
22
|
-
catch {
|
|
23
|
-
return null;
|
|
24
|
-
}
|
|
25
|
-
// Next.js: /_next/static/ → .next/static/
|
|
26
|
-
if (pathname.startsWith('/_next/')) {
|
|
27
|
-
return resolve(cwd, '.next' + pathname.slice(6));
|
|
28
|
-
}
|
|
29
|
-
// Generic: resolve pathname against cwd
|
|
30
|
-
const relative = pathname.slice(1);
|
|
31
|
-
if (!relative)
|
|
32
|
-
return null;
|
|
33
|
-
return resolve(cwd, relative);
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Parse stack frames from a browser Error.stack string.
|
|
37
|
-
* Expects V8 format (Chrome stacks or pre-normalized Firefox/Safari stacks).
|
|
38
|
-
* Maps http/https URLs to local file paths using Next.js conventions.
|
|
39
|
-
*/
|
|
40
|
-
export function parseBrowserFrames(stack, cwd) {
|
|
41
|
-
const frames = [];
|
|
42
|
-
if (!stack)
|
|
43
|
-
return frames;
|
|
44
|
-
for (const line of stack.split('\n')) {
|
|
45
|
-
const m = line.match(STACK_LINE_RE);
|
|
46
|
-
if (!m)
|
|
47
|
-
continue;
|
|
48
|
-
const rawFile = m[1];
|
|
49
|
-
// Handle http/https URLs (browser stack traces)
|
|
50
|
-
if (rawFile.startsWith('http://') || rawFile.startsWith('https://')) {
|
|
51
|
-
const file = mapBrowserUrlToPath(rawFile, cwd);
|
|
52
|
-
if (!file)
|
|
53
|
-
continue;
|
|
54
|
-
if (file.includes('node_modules'))
|
|
55
|
-
continue;
|
|
56
|
-
frames.push({ file, line: parseInt(m[2], 10), column: parseInt(m[3], 10) });
|
|
57
|
-
if (frames.length >= 10)
|
|
58
|
-
break;
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
// Skip browser internals and other URL schemes
|
|
62
|
-
if (BROWSER_INTERNAL_RE.test(rawFile))
|
|
63
|
-
continue;
|
|
64
|
-
if (rawFile.startsWith('node:') || rawFile.includes('node_modules'))
|
|
65
|
-
continue;
|
|
66
|
-
frames.push({ file: rawFile, line: parseInt(m[2], 10), column: parseInt(m[3], 10) });
|
|
67
|
-
if (frames.length >= 10)
|
|
68
|
-
break;
|
|
69
|
-
}
|
|
70
|
-
return frames;
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* Extract source context lines around a target line number.
|
|
74
|
-
* Returns 5 lines before, the target line, and 5 lines after.
|
|
75
|
-
*/
|
|
76
|
-
export function extractContext(source, line) {
|
|
77
|
-
const lines = source.split('\n');
|
|
78
|
-
if (line < 1 || line > lines.length)
|
|
79
|
-
return null;
|
|
80
|
-
const start = Math.max(0, line - 6);
|
|
81
|
-
const end = Math.min(lines.length, line + 5);
|
|
82
|
-
return {
|
|
83
|
-
pre: lines.slice(start, line - 1),
|
|
84
|
-
target: lines[line - 1] || '',
|
|
85
|
-
post: lines.slice(line, end),
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
|