@designfever/web-review-kit 0.1.0 → 0.3.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.
- package/README.md +77 -179
- package/dist/{chunk-U5K2YGGL.js → chunk-I76WEDLA.js} +2248 -2722
- package/dist/chunk-I76WEDLA.js.map +1 -0
- package/dist/index.cjs +2346 -2603
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -6
- package/dist/index.d.ts +10 -6
- package/dist/index.js +220 -7
- package/dist/index.js.map +1 -1
- package/dist/react-shell.cjs +8953 -6632
- package/dist/react-shell.cjs.map +1 -1
- package/dist/react-shell.d.cts +8 -3
- package/dist/react-shell.d.ts +8 -3
- package/dist/react-shell.js +5956 -3636
- package/dist/react-shell.js.map +1 -1
- package/dist/{types-D_mNjOHx.d.cts → types-Cf2x5ky6.d.cts} +8 -14
- package/dist/{types-D_mNjOHx.d.ts → types-Cf2x5ky6.d.ts} +8 -14
- package/dist/vite.cjs +186 -0
- package/dist/vite.cjs.map +1 -0
- package/dist/vite.d.cts +16 -0
- package/dist/vite.d.ts +16 -0
- package/dist/vite.js +161 -0
- package/dist/vite.js.map +1 -0
- package/docs/README.md +21 -30
- package/docs/adaptor.sample.ts +182 -0
- package/docs/architecture.md +125 -0
- package/docs/db-setup.md +253 -0
- package/docs/figma-overlay.md +52 -0
- package/docs/grid-overlay.md +38 -0
- package/docs/installation.md +108 -40
- package/package.json +22 -6
- package/dist/chunk-U5K2YGGL.js.map +0 -1
- package/docs/adapter-handoff.md +0 -146
- package/docs/concept.md +0 -102
- package/docs/df-sheet-adapter.md +0 -336
- package/docs/df-sheet-next.md +0 -222
- package/docs/initial-plan.md +0 -226
- package/docs/package-split-checkpoint.md +0 -79
- package/docs/presence-handoff.md +0 -138
- package/docs/review-feedback-2026-06-20.md +0 -267
- package/docs/smoke-baseline-2026-06-20.md +0 -41
- package/docs/stabilize-ui-work-guide.md +0 -243
- package/docs/supabase-presence.md +0 -198
- package/docs/supabase-review-items.md +0 -365
- package/docs/supabase.md +0 -205
|
@@ -3,7 +3,7 @@ type ReviewItemScope = 'mobile' | 'tablet' | 'desktop' | 'wide' | 'dom';
|
|
|
3
3
|
type ReviewWorkflowStatus = 'todo' | 'doing' | 'review' | 'hold' | 'done';
|
|
4
4
|
type ReviewItemStatus = 'open' | 'resolved' | ReviewWorkflowStatus;
|
|
5
5
|
type ReviewMode = 'idle' | 'note' | 'element' | 'area';
|
|
6
|
-
type ReviewSource = 'local' | '
|
|
6
|
+
type ReviewSource = 'local' | 'supabase' | (string & {});
|
|
7
7
|
type ReviewSubmitStatus = 'idle' | 'submitting' | 'submitted' | 'failed';
|
|
8
8
|
type ReviewViewportScope = Exclude<ReviewItemScope, 'dom'>;
|
|
9
9
|
type DomAnchorStrategy = 'configured-attribute' | 'id' | 'class' | 'dom-path';
|
|
@@ -20,6 +20,8 @@ interface DomAnchorCandidate {
|
|
|
20
20
|
interface DomSourceHint {
|
|
21
21
|
component?: string;
|
|
22
22
|
file?: string;
|
|
23
|
+
line?: string;
|
|
24
|
+
column?: string;
|
|
23
25
|
sectionId?: string;
|
|
24
26
|
sectionIndex?: string;
|
|
25
27
|
}
|
|
@@ -62,6 +64,7 @@ interface ReviewItem {
|
|
|
62
64
|
kind: ReviewItemKind;
|
|
63
65
|
title?: string;
|
|
64
66
|
comment: string;
|
|
67
|
+
createdBy?: string;
|
|
65
68
|
status: ReviewItemStatus;
|
|
66
69
|
viewport: ViewportSize;
|
|
67
70
|
devicePixelRatio?: number;
|
|
@@ -98,17 +101,6 @@ interface WebReviewKitAdapter {
|
|
|
98
101
|
interface LocalAdapterOptions {
|
|
99
102
|
storageKey?: string;
|
|
100
103
|
}
|
|
101
|
-
interface DfSheetAdapterOptions {
|
|
102
|
-
baseUrl?: string;
|
|
103
|
-
projectId: string;
|
|
104
|
-
pageId: string;
|
|
105
|
-
reviewProjectId?: string;
|
|
106
|
-
reviewPathPrefix?: string;
|
|
107
|
-
source?: string;
|
|
108
|
-
issueType?: string;
|
|
109
|
-
priority?: string;
|
|
110
|
-
token?: string;
|
|
111
|
-
}
|
|
112
104
|
interface SupabaseReviewClient {
|
|
113
105
|
from(table: string): any;
|
|
114
106
|
rpc?: (fn: string, args?: Record<string, unknown>) => any;
|
|
@@ -132,11 +124,12 @@ interface NumberedReviewItem {
|
|
|
132
124
|
item: ReviewItem;
|
|
133
125
|
scope: ReviewItemScope;
|
|
134
126
|
label: string;
|
|
135
|
-
number
|
|
127
|
+
number?: number;
|
|
136
128
|
displayLabel: string;
|
|
137
129
|
}
|
|
138
130
|
interface WebReviewKitOptions {
|
|
139
131
|
projectId: string;
|
|
132
|
+
userId?: string;
|
|
140
133
|
adapter?: WebReviewKitAdapter;
|
|
141
134
|
target?: WebReviewKitTarget | (() => WebReviewKitTarget | undefined);
|
|
142
135
|
viewports?: {
|
|
@@ -150,6 +143,7 @@ interface WebReviewKitOptions {
|
|
|
150
143
|
attribute?: string;
|
|
151
144
|
};
|
|
152
145
|
onRestoreItem?: (item: ReviewItem) => void | Promise<void>;
|
|
146
|
+
onCreateItem?: (item: ReviewItem) => void | Promise<void>;
|
|
153
147
|
onItemsChange?: (items: ReviewItem[]) => void;
|
|
154
148
|
onModeChange?: (mode: ReviewMode) => void;
|
|
155
149
|
ui?: {
|
|
@@ -180,4 +174,4 @@ interface WebReviewKitTarget {
|
|
|
180
174
|
getOverlayRect?: () => Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>;
|
|
181
175
|
}
|
|
182
176
|
|
|
183
|
-
export type {
|
|
177
|
+
export type { DomAnchor as D, LocalAdapterOptions as L, NumberedReviewItem as N, ReviewWorkflowStatus as R, SupabaseReviewAdapterOptions as S, ViewportSize as V, WebReviewKitAdapter as W, ReviewItemStatus as a, WebReviewKitOptions as b, WebReviewKitController as c, ReviewViewportPreset as d, ReviewItem as e, ReviewItemScope as f, DomAnchorCandidate as g, DomAnchorStrategy as h, DomSourceHint as i, RelativeSelection as j, ReviewItemKind as k, ReviewItemQuery as l, ReviewMarker as m, ReviewMode as n, ReviewPoint as o, ReviewRulerConfig as p, ReviewSelection as q, ReviewSource as r, ReviewSubmitStatus as s, ReviewViewportScope as t, SupabaseReviewClient as u, WebReviewKitTarget as v };
|
|
@@ -3,7 +3,7 @@ type ReviewItemScope = 'mobile' | 'tablet' | 'desktop' | 'wide' | 'dom';
|
|
|
3
3
|
type ReviewWorkflowStatus = 'todo' | 'doing' | 'review' | 'hold' | 'done';
|
|
4
4
|
type ReviewItemStatus = 'open' | 'resolved' | ReviewWorkflowStatus;
|
|
5
5
|
type ReviewMode = 'idle' | 'note' | 'element' | 'area';
|
|
6
|
-
type ReviewSource = 'local' | '
|
|
6
|
+
type ReviewSource = 'local' | 'supabase' | (string & {});
|
|
7
7
|
type ReviewSubmitStatus = 'idle' | 'submitting' | 'submitted' | 'failed';
|
|
8
8
|
type ReviewViewportScope = Exclude<ReviewItemScope, 'dom'>;
|
|
9
9
|
type DomAnchorStrategy = 'configured-attribute' | 'id' | 'class' | 'dom-path';
|
|
@@ -20,6 +20,8 @@ interface DomAnchorCandidate {
|
|
|
20
20
|
interface DomSourceHint {
|
|
21
21
|
component?: string;
|
|
22
22
|
file?: string;
|
|
23
|
+
line?: string;
|
|
24
|
+
column?: string;
|
|
23
25
|
sectionId?: string;
|
|
24
26
|
sectionIndex?: string;
|
|
25
27
|
}
|
|
@@ -62,6 +64,7 @@ interface ReviewItem {
|
|
|
62
64
|
kind: ReviewItemKind;
|
|
63
65
|
title?: string;
|
|
64
66
|
comment: string;
|
|
67
|
+
createdBy?: string;
|
|
65
68
|
status: ReviewItemStatus;
|
|
66
69
|
viewport: ViewportSize;
|
|
67
70
|
devicePixelRatio?: number;
|
|
@@ -98,17 +101,6 @@ interface WebReviewKitAdapter {
|
|
|
98
101
|
interface LocalAdapterOptions {
|
|
99
102
|
storageKey?: string;
|
|
100
103
|
}
|
|
101
|
-
interface DfSheetAdapterOptions {
|
|
102
|
-
baseUrl?: string;
|
|
103
|
-
projectId: string;
|
|
104
|
-
pageId: string;
|
|
105
|
-
reviewProjectId?: string;
|
|
106
|
-
reviewPathPrefix?: string;
|
|
107
|
-
source?: string;
|
|
108
|
-
issueType?: string;
|
|
109
|
-
priority?: string;
|
|
110
|
-
token?: string;
|
|
111
|
-
}
|
|
112
104
|
interface SupabaseReviewClient {
|
|
113
105
|
from(table: string): any;
|
|
114
106
|
rpc?: (fn: string, args?: Record<string, unknown>) => any;
|
|
@@ -132,11 +124,12 @@ interface NumberedReviewItem {
|
|
|
132
124
|
item: ReviewItem;
|
|
133
125
|
scope: ReviewItemScope;
|
|
134
126
|
label: string;
|
|
135
|
-
number
|
|
127
|
+
number?: number;
|
|
136
128
|
displayLabel: string;
|
|
137
129
|
}
|
|
138
130
|
interface WebReviewKitOptions {
|
|
139
131
|
projectId: string;
|
|
132
|
+
userId?: string;
|
|
140
133
|
adapter?: WebReviewKitAdapter;
|
|
141
134
|
target?: WebReviewKitTarget | (() => WebReviewKitTarget | undefined);
|
|
142
135
|
viewports?: {
|
|
@@ -150,6 +143,7 @@ interface WebReviewKitOptions {
|
|
|
150
143
|
attribute?: string;
|
|
151
144
|
};
|
|
152
145
|
onRestoreItem?: (item: ReviewItem) => void | Promise<void>;
|
|
146
|
+
onCreateItem?: (item: ReviewItem) => void | Promise<void>;
|
|
153
147
|
onItemsChange?: (items: ReviewItem[]) => void;
|
|
154
148
|
onModeChange?: (mode: ReviewMode) => void;
|
|
155
149
|
ui?: {
|
|
@@ -180,4 +174,4 @@ interface WebReviewKitTarget {
|
|
|
180
174
|
getOverlayRect?: () => Pick<DOMRect, 'left' | 'top' | 'width' | 'height'>;
|
|
181
175
|
}
|
|
182
176
|
|
|
183
|
-
export type {
|
|
177
|
+
export type { DomAnchor as D, LocalAdapterOptions as L, NumberedReviewItem as N, ReviewWorkflowStatus as R, SupabaseReviewAdapterOptions as S, ViewportSize as V, WebReviewKitAdapter as W, ReviewItemStatus as a, WebReviewKitOptions as b, WebReviewKitController as c, ReviewViewportPreset as d, ReviewItem as e, ReviewItemScope as f, DomAnchorCandidate as g, DomAnchorStrategy as h, DomSourceHint as i, RelativeSelection as j, ReviewItemKind as k, ReviewItemQuery as l, ReviewMarker as m, ReviewMode as n, ReviewPoint as o, ReviewRulerConfig as p, ReviewSelection as q, ReviewSource as r, ReviewSubmitStatus as s, ReviewViewportScope as t, SupabaseReviewClient as u, WebReviewKitTarget as v };
|
package/dist/vite.cjs
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/vite.ts
|
|
21
|
+
var vite_exports = {};
|
|
22
|
+
__export(vite_exports, {
|
|
23
|
+
reviewSourceLocator: () => reviewSourceLocator
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(vite_exports);
|
|
26
|
+
var VIRTUAL_JSX_DEV_RUNTIME_ID = "\0@designfever/web-review-kit/source-locator/jsx-dev-runtime";
|
|
27
|
+
var reviewSourceLocator = (options = {}) => {
|
|
28
|
+
let runtimeOptions = createRuntimeOptions(options);
|
|
29
|
+
return {
|
|
30
|
+
name: "df-web-review-kit-source-locator",
|
|
31
|
+
enforce: "pre",
|
|
32
|
+
configResolved(config) {
|
|
33
|
+
runtimeOptions = createRuntimeOptions(options, config);
|
|
34
|
+
},
|
|
35
|
+
resolveId(id, importer) {
|
|
36
|
+
if (!runtimeOptions.enabled) return null;
|
|
37
|
+
if (id !== "react/jsx-dev-runtime") return null;
|
|
38
|
+
if (importer === VIRTUAL_JSX_DEV_RUNTIME_ID) return null;
|
|
39
|
+
return VIRTUAL_JSX_DEV_RUNTIME_ID;
|
|
40
|
+
},
|
|
41
|
+
load(id) {
|
|
42
|
+
if (id !== VIRTUAL_JSX_DEV_RUNTIME_ID) return null;
|
|
43
|
+
return createJsxDevRuntime(runtimeOptions);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
function createRuntimeOptions(options, config) {
|
|
48
|
+
const attributePrefix = (options.attributePrefix ?? "data-wrk-source").replace(
|
|
49
|
+
/-+$/,
|
|
50
|
+
""
|
|
51
|
+
);
|
|
52
|
+
const root = normalizePath(options.root ?? config?.root ?? "");
|
|
53
|
+
const enabled = options.enabled ?? config?.command === "serve";
|
|
54
|
+
return {
|
|
55
|
+
enabled,
|
|
56
|
+
root,
|
|
57
|
+
include: (options.include ?? []).map(createRuntimeMatcher),
|
|
58
|
+
exclude: (options.exclude ?? ["node_modules", "dist"]).map(
|
|
59
|
+
createRuntimeMatcher
|
|
60
|
+
),
|
|
61
|
+
filePath: options.filePath ?? "relative",
|
|
62
|
+
line: options.line ?? true,
|
|
63
|
+
column: options.column ?? true,
|
|
64
|
+
fileAttribute: `${attributePrefix}-file`,
|
|
65
|
+
lineAttribute: `${attributePrefix}-line`,
|
|
66
|
+
columnAttribute: `${attributePrefix}-column`
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function createRuntimeMatcher(pattern) {
|
|
70
|
+
if (pattern instanceof RegExp) {
|
|
71
|
+
return { type: "regex", value: pattern.source, flags: pattern.flags };
|
|
72
|
+
}
|
|
73
|
+
return { type: "path", value: normalizePath(pattern).replace(/^\.\//, "") };
|
|
74
|
+
}
|
|
75
|
+
function normalizePath(value) {
|
|
76
|
+
return value.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
77
|
+
}
|
|
78
|
+
function createJsxDevRuntime(options) {
|
|
79
|
+
return `
|
|
80
|
+
import { Fragment, jsxDEV as baseJsxDEV } from 'react/jsx-dev-runtime';
|
|
81
|
+
|
|
82
|
+
const OPTIONS = ${JSON.stringify(options)};
|
|
83
|
+
|
|
84
|
+
export { Fragment };
|
|
85
|
+
|
|
86
|
+
export function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
|
87
|
+
return baseJsxDEV(
|
|
88
|
+
type,
|
|
89
|
+
injectSourceProps(type, props, source),
|
|
90
|
+
key,
|
|
91
|
+
isStaticChildren,
|
|
92
|
+
source,
|
|
93
|
+
self
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function injectSourceProps(type, props, source) {
|
|
98
|
+
if (typeof type !== 'string') return props;
|
|
99
|
+
if (!source || typeof source.fileName !== 'string') return props;
|
|
100
|
+
|
|
101
|
+
const sourceFile = getSourceFile(source.fileName);
|
|
102
|
+
if (!sourceFile) return props;
|
|
103
|
+
|
|
104
|
+
const nextProps = props ? { ...props } : {};
|
|
105
|
+
if (nextProps[OPTIONS.fileAttribute] == null) {
|
|
106
|
+
nextProps[OPTIONS.fileAttribute] = sourceFile;
|
|
107
|
+
}
|
|
108
|
+
if (OPTIONS.line && source.lineNumber != null && nextProps[OPTIONS.lineAttribute] == null) {
|
|
109
|
+
nextProps[OPTIONS.lineAttribute] = String(source.lineNumber);
|
|
110
|
+
}
|
|
111
|
+
if (OPTIONS.column && source.columnNumber != null && nextProps[OPTIONS.columnAttribute] == null) {
|
|
112
|
+
nextProps[OPTIONS.columnAttribute] = String(source.columnNumber);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return nextProps;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function getSourceFile(fileName) {
|
|
119
|
+
const absoluteFile = normalizePath(fileName);
|
|
120
|
+
const relativeFile = getRelativeFile(absoluteFile);
|
|
121
|
+
|
|
122
|
+
if (OPTIONS.include.length > 0 && !matchesAny(OPTIONS.include, absoluteFile, relativeFile)) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
if (matchesAny(OPTIONS.exclude, absoluteFile, relativeFile)) return null;
|
|
126
|
+
|
|
127
|
+
return OPTIONS.filePath === 'absolute' ? absoluteFile : relativeFile;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function getRelativeFile(absoluteFile) {
|
|
131
|
+
if (!OPTIONS.root) return absoluteFile;
|
|
132
|
+
if (absoluteFile === OPTIONS.root) return '';
|
|
133
|
+
if (absoluteFile.startsWith(OPTIONS.root + '/')) {
|
|
134
|
+
return absoluteFile.slice(OPTIONS.root.length + 1);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return absoluteFile;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
function matchesAny(patterns, absoluteFile, relativeFile) {
|
|
141
|
+
return patterns.some((pattern) =>
|
|
142
|
+
matchesPattern(pattern, absoluteFile, relativeFile)
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function matchesPattern(pattern, absoluteFile, relativeFile) {
|
|
147
|
+
if (pattern.type === 'regex') {
|
|
148
|
+
const regex = new RegExp(pattern.value, pattern.flags);
|
|
149
|
+
return regex.test(absoluteFile) || regex.test(relativeFile);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const value = pattern.value;
|
|
153
|
+
const target = isAbsolutePattern(value) ? absoluteFile : relativeFile;
|
|
154
|
+
if (!value.includes('*')) {
|
|
155
|
+
return target === value || target.startsWith(value + '/');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return globToRegExp(value).test(target);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function isAbsolutePattern(value) {
|
|
162
|
+
return value.startsWith('/') || /^[a-zA-Z]:\\//.test(value);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function globToRegExp(value) {
|
|
166
|
+
const source = escapeRegExp(value)
|
|
167
|
+
.replace(/\\\\\\*\\\\\\*/g, '.*')
|
|
168
|
+
.replace(/\\\\\\*/g, '[^/]*');
|
|
169
|
+
|
|
170
|
+
return new RegExp('^' + source + '$');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function escapeRegExp(value) {
|
|
174
|
+
return value.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function normalizePath(value) {
|
|
178
|
+
return value.replace(/\\\\/g, '/').replace(/\\/+$/, '');
|
|
179
|
+
}
|
|
180
|
+
`;
|
|
181
|
+
}
|
|
182
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
183
|
+
0 && (module.exports = {
|
|
184
|
+
reviewSourceLocator
|
|
185
|
+
});
|
|
186
|
+
//# sourceMappingURL=vite.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/vite.ts"],"sourcesContent":["import type { Plugin, ResolvedConfig } from 'vite';\n\ntype SourceLocatorPattern = string | RegExp;\n\nexport interface ReviewSourceLocatorOptions {\n enabled?: boolean;\n root?: string;\n include?: readonly SourceLocatorPattern[];\n exclude?: readonly SourceLocatorPattern[];\n filePath?: 'relative' | 'absolute';\n line?: boolean;\n column?: boolean;\n attributePrefix?: string;\n}\n\ntype RuntimeMatcher =\n | { type: 'path'; value: string }\n | { type: 'regex'; value: string; flags: string };\n\ntype RuntimeOptions = {\n enabled: boolean;\n root: string;\n include: RuntimeMatcher[];\n exclude: RuntimeMatcher[];\n filePath: 'relative' | 'absolute';\n line: boolean;\n column: boolean;\n fileAttribute: string;\n lineAttribute: string;\n columnAttribute: string;\n};\n\nconst VIRTUAL_JSX_DEV_RUNTIME_ID =\n '\\0@designfever/web-review-kit/source-locator/jsx-dev-runtime';\n\nexport const reviewSourceLocator = (\n options: ReviewSourceLocatorOptions = {}\n): Plugin => {\n let runtimeOptions = createRuntimeOptions(options);\n\n return {\n name: 'df-web-review-kit-source-locator',\n enforce: 'pre',\n configResolved(config) {\n runtimeOptions = createRuntimeOptions(options, config);\n },\n resolveId(id, importer) {\n if (!runtimeOptions.enabled) return null;\n if (id !== 'react/jsx-dev-runtime') return null;\n if (importer === VIRTUAL_JSX_DEV_RUNTIME_ID) return null;\n\n return VIRTUAL_JSX_DEV_RUNTIME_ID;\n },\n load(id) {\n if (id !== VIRTUAL_JSX_DEV_RUNTIME_ID) return null;\n return createJsxDevRuntime(runtimeOptions);\n },\n };\n};\n\nfunction createRuntimeOptions(\n options: ReviewSourceLocatorOptions,\n config?: ResolvedConfig\n): RuntimeOptions {\n const attributePrefix = (options.attributePrefix ?? 'data-wrk-source').replace(\n /-+$/,\n ''\n );\n const root = normalizePath(options.root ?? config?.root ?? '');\n const enabled = options.enabled ?? (config?.command === 'serve');\n\n return {\n enabled,\n root,\n include: (options.include ?? []).map(createRuntimeMatcher),\n exclude: (options.exclude ?? ['node_modules', 'dist']).map(\n createRuntimeMatcher\n ),\n filePath: options.filePath ?? 'relative',\n line: options.line ?? true,\n column: options.column ?? true,\n fileAttribute: `${attributePrefix}-file`,\n lineAttribute: `${attributePrefix}-line`,\n columnAttribute: `${attributePrefix}-column`,\n };\n}\n\nfunction createRuntimeMatcher(pattern: SourceLocatorPattern): RuntimeMatcher {\n if (pattern instanceof RegExp) {\n return { type: 'regex', value: pattern.source, flags: pattern.flags };\n }\n\n return { type: 'path', value: normalizePath(pattern).replace(/^\\.\\//, '') };\n}\n\nfunction normalizePath(value: string) {\n return value.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n}\n\nfunction createJsxDevRuntime(options: RuntimeOptions) {\n return `\nimport { Fragment, jsxDEV as baseJsxDEV } from 'react/jsx-dev-runtime';\n\nconst OPTIONS = ${JSON.stringify(options)};\n\nexport { Fragment };\n\nexport function jsxDEV(type, props, key, isStaticChildren, source, self) {\n return baseJsxDEV(\n type,\n injectSourceProps(type, props, source),\n key,\n isStaticChildren,\n source,\n self\n );\n}\n\nfunction injectSourceProps(type, props, source) {\n if (typeof type !== 'string') return props;\n if (!source || typeof source.fileName !== 'string') return props;\n\n const sourceFile = getSourceFile(source.fileName);\n if (!sourceFile) return props;\n\n const nextProps = props ? { ...props } : {};\n if (nextProps[OPTIONS.fileAttribute] == null) {\n nextProps[OPTIONS.fileAttribute] = sourceFile;\n }\n if (OPTIONS.line && source.lineNumber != null && nextProps[OPTIONS.lineAttribute] == null) {\n nextProps[OPTIONS.lineAttribute] = String(source.lineNumber);\n }\n if (OPTIONS.column && source.columnNumber != null && nextProps[OPTIONS.columnAttribute] == null) {\n nextProps[OPTIONS.columnAttribute] = String(source.columnNumber);\n }\n\n return nextProps;\n}\n\nfunction getSourceFile(fileName) {\n const absoluteFile = normalizePath(fileName);\n const relativeFile = getRelativeFile(absoluteFile);\n\n if (OPTIONS.include.length > 0 && !matchesAny(OPTIONS.include, absoluteFile, relativeFile)) {\n return null;\n }\n if (matchesAny(OPTIONS.exclude, absoluteFile, relativeFile)) return null;\n\n return OPTIONS.filePath === 'absolute' ? absoluteFile : relativeFile;\n}\n\nfunction getRelativeFile(absoluteFile) {\n if (!OPTIONS.root) return absoluteFile;\n if (absoluteFile === OPTIONS.root) return '';\n if (absoluteFile.startsWith(OPTIONS.root + '/')) {\n return absoluteFile.slice(OPTIONS.root.length + 1);\n }\n\n return absoluteFile;\n}\n\nfunction matchesAny(patterns, absoluteFile, relativeFile) {\n return patterns.some((pattern) =>\n matchesPattern(pattern, absoluteFile, relativeFile)\n );\n}\n\nfunction matchesPattern(pattern, absoluteFile, relativeFile) {\n if (pattern.type === 'regex') {\n const regex = new RegExp(pattern.value, pattern.flags);\n return regex.test(absoluteFile) || regex.test(relativeFile);\n }\n\n const value = pattern.value;\n const target = isAbsolutePattern(value) ? absoluteFile : relativeFile;\n if (!value.includes('*')) {\n return target === value || target.startsWith(value + '/');\n }\n\n return globToRegExp(value).test(target);\n}\n\nfunction isAbsolutePattern(value) {\n return value.startsWith('/') || /^[a-zA-Z]:\\\\//.test(value);\n}\n\nfunction globToRegExp(value) {\n const source = escapeRegExp(value)\n .replace(/\\\\\\\\\\\\*\\\\\\\\\\\\*/g, '.*')\n .replace(/\\\\\\\\\\\\*/g, '[^/]*');\n\n return new RegExp('^' + source + '$');\n}\n\nfunction escapeRegExp(value) {\n return value.replace(/[|\\\\\\\\{}()[\\\\]^$+*?.]/g, '\\\\\\\\$&');\n}\n\nfunction normalizePath(value) {\n return value.replace(/\\\\\\\\/g, '/').replace(/\\\\/+$/, '');\n}\n`;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgCA,IAAM,6BACJ;AAEK,IAAM,sBAAsB,CACjC,UAAsC,CAAC,MAC5B;AACX,MAAI,iBAAiB,qBAAqB,OAAO;AAEjD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,eAAe,QAAQ;AACrB,uBAAiB,qBAAqB,SAAS,MAAM;AAAA,IACvD;AAAA,IACA,UAAU,IAAI,UAAU;AACtB,UAAI,CAAC,eAAe,QAAS,QAAO;AACpC,UAAI,OAAO,wBAAyB,QAAO;AAC3C,UAAI,aAAa,2BAA4B,QAAO;AAEpD,aAAO;AAAA,IACT;AAAA,IACA,KAAK,IAAI;AACP,UAAI,OAAO,2BAA4B,QAAO;AAC9C,aAAO,oBAAoB,cAAc;AAAA,IAC3C;AAAA,EACF;AACF;AAEA,SAAS,qBACP,SACA,QACgB;AAChB,QAAM,mBAAmB,QAAQ,mBAAmB,mBAAmB;AAAA,IACrE;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,cAAc,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AAC7D,QAAM,UAAU,QAAQ,WAAY,QAAQ,YAAY;AAExD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,QAAQ,WAAW,CAAC,GAAG,IAAI,oBAAoB;AAAA,IACzD,UAAU,QAAQ,WAAW,CAAC,gBAAgB,MAAM,GAAG;AAAA,MACrD;AAAA,IACF;AAAA,IACA,UAAU,QAAQ,YAAY;AAAA,IAC9B,MAAM,QAAQ,QAAQ;AAAA,IACtB,QAAQ,QAAQ,UAAU;AAAA,IAC1B,eAAe,GAAG,eAAe;AAAA,IACjC,eAAe,GAAG,eAAe;AAAA,IACjC,iBAAiB,GAAG,eAAe;AAAA,EACrC;AACF;AAEA,SAAS,qBAAqB,SAA+C;AAC3E,MAAI,mBAAmB,QAAQ;AAC7B,WAAO,EAAE,MAAM,SAAS,OAAO,QAAQ,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtE;AAEA,SAAO,EAAE,MAAM,QAAQ,OAAO,cAAc,OAAO,EAAE,QAAQ,SAAS,EAAE,EAAE;AAC5E;AAEA,SAAS,cAAc,OAAe;AACpC,SAAO,MAAM,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE;AACrD;AAEA,SAAS,oBAAoB,SAAyB;AACpD,SAAO;AAAA;AAAA;AAAA,kBAGS,KAAK,UAAU,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmGzC;","names":[]}
|
package/dist/vite.d.cts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
type SourceLocatorPattern = string | RegExp;
|
|
4
|
+
interface ReviewSourceLocatorOptions {
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
root?: string;
|
|
7
|
+
include?: readonly SourceLocatorPattern[];
|
|
8
|
+
exclude?: readonly SourceLocatorPattern[];
|
|
9
|
+
filePath?: 'relative' | 'absolute';
|
|
10
|
+
line?: boolean;
|
|
11
|
+
column?: boolean;
|
|
12
|
+
attributePrefix?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const reviewSourceLocator: (options?: ReviewSourceLocatorOptions) => Plugin;
|
|
15
|
+
|
|
16
|
+
export { type ReviewSourceLocatorOptions, reviewSourceLocator };
|
package/dist/vite.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Plugin } from 'vite';
|
|
2
|
+
|
|
3
|
+
type SourceLocatorPattern = string | RegExp;
|
|
4
|
+
interface ReviewSourceLocatorOptions {
|
|
5
|
+
enabled?: boolean;
|
|
6
|
+
root?: string;
|
|
7
|
+
include?: readonly SourceLocatorPattern[];
|
|
8
|
+
exclude?: readonly SourceLocatorPattern[];
|
|
9
|
+
filePath?: 'relative' | 'absolute';
|
|
10
|
+
line?: boolean;
|
|
11
|
+
column?: boolean;
|
|
12
|
+
attributePrefix?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const reviewSourceLocator: (options?: ReviewSourceLocatorOptions) => Plugin;
|
|
15
|
+
|
|
16
|
+
export { type ReviewSourceLocatorOptions, reviewSourceLocator };
|
package/dist/vite.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
// src/vite.ts
|
|
2
|
+
var VIRTUAL_JSX_DEV_RUNTIME_ID = "\0@designfever/web-review-kit/source-locator/jsx-dev-runtime";
|
|
3
|
+
var reviewSourceLocator = (options = {}) => {
|
|
4
|
+
let runtimeOptions = createRuntimeOptions(options);
|
|
5
|
+
return {
|
|
6
|
+
name: "df-web-review-kit-source-locator",
|
|
7
|
+
enforce: "pre",
|
|
8
|
+
configResolved(config) {
|
|
9
|
+
runtimeOptions = createRuntimeOptions(options, config);
|
|
10
|
+
},
|
|
11
|
+
resolveId(id, importer) {
|
|
12
|
+
if (!runtimeOptions.enabled) return null;
|
|
13
|
+
if (id !== "react/jsx-dev-runtime") return null;
|
|
14
|
+
if (importer === VIRTUAL_JSX_DEV_RUNTIME_ID) return null;
|
|
15
|
+
return VIRTUAL_JSX_DEV_RUNTIME_ID;
|
|
16
|
+
},
|
|
17
|
+
load(id) {
|
|
18
|
+
if (id !== VIRTUAL_JSX_DEV_RUNTIME_ID) return null;
|
|
19
|
+
return createJsxDevRuntime(runtimeOptions);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
function createRuntimeOptions(options, config) {
|
|
24
|
+
const attributePrefix = (options.attributePrefix ?? "data-wrk-source").replace(
|
|
25
|
+
/-+$/,
|
|
26
|
+
""
|
|
27
|
+
);
|
|
28
|
+
const root = normalizePath(options.root ?? config?.root ?? "");
|
|
29
|
+
const enabled = options.enabled ?? config?.command === "serve";
|
|
30
|
+
return {
|
|
31
|
+
enabled,
|
|
32
|
+
root,
|
|
33
|
+
include: (options.include ?? []).map(createRuntimeMatcher),
|
|
34
|
+
exclude: (options.exclude ?? ["node_modules", "dist"]).map(
|
|
35
|
+
createRuntimeMatcher
|
|
36
|
+
),
|
|
37
|
+
filePath: options.filePath ?? "relative",
|
|
38
|
+
line: options.line ?? true,
|
|
39
|
+
column: options.column ?? true,
|
|
40
|
+
fileAttribute: `${attributePrefix}-file`,
|
|
41
|
+
lineAttribute: `${attributePrefix}-line`,
|
|
42
|
+
columnAttribute: `${attributePrefix}-column`
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function createRuntimeMatcher(pattern) {
|
|
46
|
+
if (pattern instanceof RegExp) {
|
|
47
|
+
return { type: "regex", value: pattern.source, flags: pattern.flags };
|
|
48
|
+
}
|
|
49
|
+
return { type: "path", value: normalizePath(pattern).replace(/^\.\//, "") };
|
|
50
|
+
}
|
|
51
|
+
function normalizePath(value) {
|
|
52
|
+
return value.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
53
|
+
}
|
|
54
|
+
function createJsxDevRuntime(options) {
|
|
55
|
+
return `
|
|
56
|
+
import { Fragment, jsxDEV as baseJsxDEV } from 'react/jsx-dev-runtime';
|
|
57
|
+
|
|
58
|
+
const OPTIONS = ${JSON.stringify(options)};
|
|
59
|
+
|
|
60
|
+
export { Fragment };
|
|
61
|
+
|
|
62
|
+
export function jsxDEV(type, props, key, isStaticChildren, source, self) {
|
|
63
|
+
return baseJsxDEV(
|
|
64
|
+
type,
|
|
65
|
+
injectSourceProps(type, props, source),
|
|
66
|
+
key,
|
|
67
|
+
isStaticChildren,
|
|
68
|
+
source,
|
|
69
|
+
self
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function injectSourceProps(type, props, source) {
|
|
74
|
+
if (typeof type !== 'string') return props;
|
|
75
|
+
if (!source || typeof source.fileName !== 'string') return props;
|
|
76
|
+
|
|
77
|
+
const sourceFile = getSourceFile(source.fileName);
|
|
78
|
+
if (!sourceFile) return props;
|
|
79
|
+
|
|
80
|
+
const nextProps = props ? { ...props } : {};
|
|
81
|
+
if (nextProps[OPTIONS.fileAttribute] == null) {
|
|
82
|
+
nextProps[OPTIONS.fileAttribute] = sourceFile;
|
|
83
|
+
}
|
|
84
|
+
if (OPTIONS.line && source.lineNumber != null && nextProps[OPTIONS.lineAttribute] == null) {
|
|
85
|
+
nextProps[OPTIONS.lineAttribute] = String(source.lineNumber);
|
|
86
|
+
}
|
|
87
|
+
if (OPTIONS.column && source.columnNumber != null && nextProps[OPTIONS.columnAttribute] == null) {
|
|
88
|
+
nextProps[OPTIONS.columnAttribute] = String(source.columnNumber);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return nextProps;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function getSourceFile(fileName) {
|
|
95
|
+
const absoluteFile = normalizePath(fileName);
|
|
96
|
+
const relativeFile = getRelativeFile(absoluteFile);
|
|
97
|
+
|
|
98
|
+
if (OPTIONS.include.length > 0 && !matchesAny(OPTIONS.include, absoluteFile, relativeFile)) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
if (matchesAny(OPTIONS.exclude, absoluteFile, relativeFile)) return null;
|
|
102
|
+
|
|
103
|
+
return OPTIONS.filePath === 'absolute' ? absoluteFile : relativeFile;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function getRelativeFile(absoluteFile) {
|
|
107
|
+
if (!OPTIONS.root) return absoluteFile;
|
|
108
|
+
if (absoluteFile === OPTIONS.root) return '';
|
|
109
|
+
if (absoluteFile.startsWith(OPTIONS.root + '/')) {
|
|
110
|
+
return absoluteFile.slice(OPTIONS.root.length + 1);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return absoluteFile;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function matchesAny(patterns, absoluteFile, relativeFile) {
|
|
117
|
+
return patterns.some((pattern) =>
|
|
118
|
+
matchesPattern(pattern, absoluteFile, relativeFile)
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function matchesPattern(pattern, absoluteFile, relativeFile) {
|
|
123
|
+
if (pattern.type === 'regex') {
|
|
124
|
+
const regex = new RegExp(pattern.value, pattern.flags);
|
|
125
|
+
return regex.test(absoluteFile) || regex.test(relativeFile);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const value = pattern.value;
|
|
129
|
+
const target = isAbsolutePattern(value) ? absoluteFile : relativeFile;
|
|
130
|
+
if (!value.includes('*')) {
|
|
131
|
+
return target === value || target.startsWith(value + '/');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return globToRegExp(value).test(target);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function isAbsolutePattern(value) {
|
|
138
|
+
return value.startsWith('/') || /^[a-zA-Z]:\\//.test(value);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function globToRegExp(value) {
|
|
142
|
+
const source = escapeRegExp(value)
|
|
143
|
+
.replace(/\\\\\\*\\\\\\*/g, '.*')
|
|
144
|
+
.replace(/\\\\\\*/g, '[^/]*');
|
|
145
|
+
|
|
146
|
+
return new RegExp('^' + source + '$');
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function escapeRegExp(value) {
|
|
150
|
+
return value.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&');
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function normalizePath(value) {
|
|
154
|
+
return value.replace(/\\\\/g, '/').replace(/\\/+$/, '');
|
|
155
|
+
}
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
export {
|
|
159
|
+
reviewSourceLocator
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=vite.js.map
|
package/dist/vite.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/vite.ts"],"sourcesContent":["import type { Plugin, ResolvedConfig } from 'vite';\n\ntype SourceLocatorPattern = string | RegExp;\n\nexport interface ReviewSourceLocatorOptions {\n enabled?: boolean;\n root?: string;\n include?: readonly SourceLocatorPattern[];\n exclude?: readonly SourceLocatorPattern[];\n filePath?: 'relative' | 'absolute';\n line?: boolean;\n column?: boolean;\n attributePrefix?: string;\n}\n\ntype RuntimeMatcher =\n | { type: 'path'; value: string }\n | { type: 'regex'; value: string; flags: string };\n\ntype RuntimeOptions = {\n enabled: boolean;\n root: string;\n include: RuntimeMatcher[];\n exclude: RuntimeMatcher[];\n filePath: 'relative' | 'absolute';\n line: boolean;\n column: boolean;\n fileAttribute: string;\n lineAttribute: string;\n columnAttribute: string;\n};\n\nconst VIRTUAL_JSX_DEV_RUNTIME_ID =\n '\\0@designfever/web-review-kit/source-locator/jsx-dev-runtime';\n\nexport const reviewSourceLocator = (\n options: ReviewSourceLocatorOptions = {}\n): Plugin => {\n let runtimeOptions = createRuntimeOptions(options);\n\n return {\n name: 'df-web-review-kit-source-locator',\n enforce: 'pre',\n configResolved(config) {\n runtimeOptions = createRuntimeOptions(options, config);\n },\n resolveId(id, importer) {\n if (!runtimeOptions.enabled) return null;\n if (id !== 'react/jsx-dev-runtime') return null;\n if (importer === VIRTUAL_JSX_DEV_RUNTIME_ID) return null;\n\n return VIRTUAL_JSX_DEV_RUNTIME_ID;\n },\n load(id) {\n if (id !== VIRTUAL_JSX_DEV_RUNTIME_ID) return null;\n return createJsxDevRuntime(runtimeOptions);\n },\n };\n};\n\nfunction createRuntimeOptions(\n options: ReviewSourceLocatorOptions,\n config?: ResolvedConfig\n): RuntimeOptions {\n const attributePrefix = (options.attributePrefix ?? 'data-wrk-source').replace(\n /-+$/,\n ''\n );\n const root = normalizePath(options.root ?? config?.root ?? '');\n const enabled = options.enabled ?? (config?.command === 'serve');\n\n return {\n enabled,\n root,\n include: (options.include ?? []).map(createRuntimeMatcher),\n exclude: (options.exclude ?? ['node_modules', 'dist']).map(\n createRuntimeMatcher\n ),\n filePath: options.filePath ?? 'relative',\n line: options.line ?? true,\n column: options.column ?? true,\n fileAttribute: `${attributePrefix}-file`,\n lineAttribute: `${attributePrefix}-line`,\n columnAttribute: `${attributePrefix}-column`,\n };\n}\n\nfunction createRuntimeMatcher(pattern: SourceLocatorPattern): RuntimeMatcher {\n if (pattern instanceof RegExp) {\n return { type: 'regex', value: pattern.source, flags: pattern.flags };\n }\n\n return { type: 'path', value: normalizePath(pattern).replace(/^\\.\\//, '') };\n}\n\nfunction normalizePath(value: string) {\n return value.replace(/\\\\/g, '/').replace(/\\/+$/, '');\n}\n\nfunction createJsxDevRuntime(options: RuntimeOptions) {\n return `\nimport { Fragment, jsxDEV as baseJsxDEV } from 'react/jsx-dev-runtime';\n\nconst OPTIONS = ${JSON.stringify(options)};\n\nexport { Fragment };\n\nexport function jsxDEV(type, props, key, isStaticChildren, source, self) {\n return baseJsxDEV(\n type,\n injectSourceProps(type, props, source),\n key,\n isStaticChildren,\n source,\n self\n );\n}\n\nfunction injectSourceProps(type, props, source) {\n if (typeof type !== 'string') return props;\n if (!source || typeof source.fileName !== 'string') return props;\n\n const sourceFile = getSourceFile(source.fileName);\n if (!sourceFile) return props;\n\n const nextProps = props ? { ...props } : {};\n if (nextProps[OPTIONS.fileAttribute] == null) {\n nextProps[OPTIONS.fileAttribute] = sourceFile;\n }\n if (OPTIONS.line && source.lineNumber != null && nextProps[OPTIONS.lineAttribute] == null) {\n nextProps[OPTIONS.lineAttribute] = String(source.lineNumber);\n }\n if (OPTIONS.column && source.columnNumber != null && nextProps[OPTIONS.columnAttribute] == null) {\n nextProps[OPTIONS.columnAttribute] = String(source.columnNumber);\n }\n\n return nextProps;\n}\n\nfunction getSourceFile(fileName) {\n const absoluteFile = normalizePath(fileName);\n const relativeFile = getRelativeFile(absoluteFile);\n\n if (OPTIONS.include.length > 0 && !matchesAny(OPTIONS.include, absoluteFile, relativeFile)) {\n return null;\n }\n if (matchesAny(OPTIONS.exclude, absoluteFile, relativeFile)) return null;\n\n return OPTIONS.filePath === 'absolute' ? absoluteFile : relativeFile;\n}\n\nfunction getRelativeFile(absoluteFile) {\n if (!OPTIONS.root) return absoluteFile;\n if (absoluteFile === OPTIONS.root) return '';\n if (absoluteFile.startsWith(OPTIONS.root + '/')) {\n return absoluteFile.slice(OPTIONS.root.length + 1);\n }\n\n return absoluteFile;\n}\n\nfunction matchesAny(patterns, absoluteFile, relativeFile) {\n return patterns.some((pattern) =>\n matchesPattern(pattern, absoluteFile, relativeFile)\n );\n}\n\nfunction matchesPattern(pattern, absoluteFile, relativeFile) {\n if (pattern.type === 'regex') {\n const regex = new RegExp(pattern.value, pattern.flags);\n return regex.test(absoluteFile) || regex.test(relativeFile);\n }\n\n const value = pattern.value;\n const target = isAbsolutePattern(value) ? absoluteFile : relativeFile;\n if (!value.includes('*')) {\n return target === value || target.startsWith(value + '/');\n }\n\n return globToRegExp(value).test(target);\n}\n\nfunction isAbsolutePattern(value) {\n return value.startsWith('/') || /^[a-zA-Z]:\\\\//.test(value);\n}\n\nfunction globToRegExp(value) {\n const source = escapeRegExp(value)\n .replace(/\\\\\\\\\\\\*\\\\\\\\\\\\*/g, '.*')\n .replace(/\\\\\\\\\\\\*/g, '[^/]*');\n\n return new RegExp('^' + source + '$');\n}\n\nfunction escapeRegExp(value) {\n return value.replace(/[|\\\\\\\\{}()[\\\\]^$+*?.]/g, '\\\\\\\\$&');\n}\n\nfunction normalizePath(value) {\n return value.replace(/\\\\\\\\/g, '/').replace(/\\\\/+$/, '');\n}\n`;\n}\n"],"mappings":";AAgCA,IAAM,6BACJ;AAEK,IAAM,sBAAsB,CACjC,UAAsC,CAAC,MAC5B;AACX,MAAI,iBAAiB,qBAAqB,OAAO;AAEjD,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,eAAe,QAAQ;AACrB,uBAAiB,qBAAqB,SAAS,MAAM;AAAA,IACvD;AAAA,IACA,UAAU,IAAI,UAAU;AACtB,UAAI,CAAC,eAAe,QAAS,QAAO;AACpC,UAAI,OAAO,wBAAyB,QAAO;AAC3C,UAAI,aAAa,2BAA4B,QAAO;AAEpD,aAAO;AAAA,IACT;AAAA,IACA,KAAK,IAAI;AACP,UAAI,OAAO,2BAA4B,QAAO;AAC9C,aAAO,oBAAoB,cAAc;AAAA,IAC3C;AAAA,EACF;AACF;AAEA,SAAS,qBACP,SACA,QACgB;AAChB,QAAM,mBAAmB,QAAQ,mBAAmB,mBAAmB;AAAA,IACrE;AAAA,IACA;AAAA,EACF;AACA,QAAM,OAAO,cAAc,QAAQ,QAAQ,QAAQ,QAAQ,EAAE;AAC7D,QAAM,UAAU,QAAQ,WAAY,QAAQ,YAAY;AAExD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,UAAU,QAAQ,WAAW,CAAC,GAAG,IAAI,oBAAoB;AAAA,IACzD,UAAU,QAAQ,WAAW,CAAC,gBAAgB,MAAM,GAAG;AAAA,MACrD;AAAA,IACF;AAAA,IACA,UAAU,QAAQ,YAAY;AAAA,IAC9B,MAAM,QAAQ,QAAQ;AAAA,IACtB,QAAQ,QAAQ,UAAU;AAAA,IAC1B,eAAe,GAAG,eAAe;AAAA,IACjC,eAAe,GAAG,eAAe;AAAA,IACjC,iBAAiB,GAAG,eAAe;AAAA,EACrC;AACF;AAEA,SAAS,qBAAqB,SAA+C;AAC3E,MAAI,mBAAmB,QAAQ;AAC7B,WAAO,EAAE,MAAM,SAAS,OAAO,QAAQ,QAAQ,OAAO,QAAQ,MAAM;AAAA,EACtE;AAEA,SAAO,EAAE,MAAM,QAAQ,OAAO,cAAc,OAAO,EAAE,QAAQ,SAAS,EAAE,EAAE;AAC5E;AAEA,SAAS,cAAc,OAAe;AACpC,SAAO,MAAM,QAAQ,OAAO,GAAG,EAAE,QAAQ,QAAQ,EAAE;AACrD;AAEA,SAAS,oBAAoB,SAAyB;AACpD,SAAO;AAAA;AAAA;AAAA,kBAGS,KAAK,UAAU,OAAO,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmGzC;","names":[]}
|
package/docs/README.md
CHANGED
|
@@ -1,37 +1,28 @@
|
|
|
1
1
|
# df-web-review-kit docs
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Public docs are intentionally small. Keep implementation history, handoff notes, and internal operator decisions out of this package documentation.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
2. [Installation](installation.md)
|
|
7
|
-
3. [Supabase setup](supabase.md)
|
|
8
|
-
4. [Supabase review item SQL](supabase-review-items.md)
|
|
9
|
-
5. [Supabase presence](supabase-presence.md)
|
|
10
|
-
6. [Adapter handoff](adapter-handoff.md)
|
|
11
|
-
7. [df-sheet next](df-sheet-next.md)
|
|
12
|
-
8. [Review feedback 2026-06-20](review-feedback-2026-06-20.md)
|
|
13
|
-
9. [Stabilize UI work guide](stabilize-ui-work-guide.md)
|
|
14
|
-
10. [Smoke baseline 2026-06-20](smoke-baseline-2026-06-20.md)
|
|
15
|
-
11. [Package split checkpoint](package-split-checkpoint.md)
|
|
5
|
+
## Read This Order
|
|
16
6
|
|
|
17
|
-
|
|
7
|
+
1. [Installation](installation.md)
|
|
8
|
+
2. [Custom adapter sample](adaptor.sample.ts)
|
|
9
|
+
3. [DB setup](db-setup.md)
|
|
10
|
+
4. [Architecture and runtime logic](architecture.md)
|
|
11
|
+
5. [Figma overlay](figma-overlay.md)
|
|
12
|
+
6. [Grid overlay](grid-overlay.md)
|
|
18
13
|
|
|
19
|
-
|
|
20
|
-
- `installation.md`: host project에 설치하고 `/review` route에 붙이는 방법.
|
|
21
|
-
- `supabase.md`: Supabase를 remote QA 저장소와 presence backend로 연결하는 방법.
|
|
22
|
-
- `supabase-review-items.md`: 실제 table/RPC/RLS SQL.
|
|
23
|
-
- `supabase-presence.md`: Supabase Realtime Presence adapter 구조.
|
|
24
|
-
- `adapter-handoff.md`: package repo로 옮길 때 필요한 adapter contract 정리.
|
|
25
|
-
- `df-sheet-next.md`: df-sheet를 source of record로 쓸 때 필요한 제품/API 방향.
|
|
26
|
-
- `review-feedback-2026-06-20.md`: 빵빵/팡팡/오빵 package 리뷰 메모와 우선순위.
|
|
27
|
-
- `stabilize-ui-work-guide.md`: anchor 안정화, UI token화, package split 전 작업 순서.
|
|
28
|
-
- `smoke-baseline-2026-06-20.md`: 761 현재 기능 smoke 기준선 결과.
|
|
29
|
-
- `package-split-checkpoint.md`: 765 package export/file/peer dependency와 host 소비 경계.
|
|
30
|
-
- `initial-plan.md`: 초기 계획 기록. 현재 기준 문서가 아니다.
|
|
14
|
+
## Document Roles
|
|
31
15
|
|
|
32
|
-
|
|
16
|
+
- `installation.md`: install the npm package, create the `/review` route, wire adapters, and run checks.
|
|
17
|
+
- `adaptor.sample.ts`: copyable starting point for host-owned remote adapters.
|
|
18
|
+
- `db-setup.md`: optional Supabase review item table/RPC/RLS/presence setup.
|
|
19
|
+
- `architecture.md`: core/runtime, React shell, coordinate, anchor, and feature boundary notes.
|
|
20
|
+
- `figma-overlay.md`: host requirements for the Figma overlay toggle.
|
|
21
|
+
- `grid-overlay.md`: host requirements for the grid/helper overlay toggle.
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
- `
|
|
37
|
-
-
|
|
23
|
+
## Boundary
|
|
24
|
+
|
|
25
|
+
- `local` is the default draft storage.
|
|
26
|
+
- `supabase` is an optional adapter sample for users who configure their own backend.
|
|
27
|
+
- `presence` is temporary session state, not QA item persistence.
|
|
28
|
+
- `kuku` and operator keys belong to OpenClaw or a backend/admin service, not this public package.
|