@spotpatch/runtime 1.11.0 → 1.13.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/dist/{chunk-QY5T4DPA.js → chunk-2WA6XVA4.js} +13 -6
- package/dist/chunk-2WA6XVA4.js.map +1 -0
- package/dist/{chunk-BXRMVHNT.js → chunk-ASRUAKA5.js} +1 -1
- package/dist/chunk-ASRUAKA5.js.map +1 -0
- package/dist/{chunk-7ES63LA7.js → chunk-P6X75LO5.js} +11 -1
- package/dist/chunk-P6X75LO5.js.map +1 -0
- package/dist/chunk-P7W3F4UA.js +115 -0
- package/dist/chunk-P7W3F4UA.js.map +1 -0
- package/dist/chunk-RZDOL5BT.js +1 -0
- package/dist/chunk-RZDOL5BT.js.map +1 -0
- package/dist/data-flow-panel.cjs +171 -0
- package/dist/data-flow-panel.cjs.map +1 -1
- package/dist/data-flow-panel.d.cts +4 -2
- package/dist/data-flow-panel.d.ts +4 -2
- package/dist/data-flow-panel.js +27 -1
- package/dist/data-flow-panel.js.map +1 -1
- package/dist/{data-flow-runtime-B3itbieT.d.cts → data-flow-runtime-DMmV0d3E.d.cts} +7 -3
- package/dist/{data-flow-runtime-B3itbieT.d.ts → data-flow-runtime-DMmV0d3E.d.ts} +7 -3
- package/dist/data-flow.cjs +12 -5
- package/dist/data-flow.cjs.map +1 -1
- package/dist/data-flow.d.cts +1 -1
- package/dist/data-flow.d.ts +1 -1
- package/dist/data-flow.js +2 -1
- package/dist/external-handoff-panel.cjs +29 -9
- package/dist/external-handoff-panel.cjs.map +1 -1
- package/dist/external-handoff-panel.d.cts +3 -3
- package/dist/external-handoff-panel.d.ts +3 -3
- package/dist/external-handoff-panel.js +22 -11
- package/dist/external-handoff-panel.js.map +1 -1
- package/dist/index.cjs +1204 -279
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1164 -355
- package/dist/index.js.map +1 -1
- package/dist/motion.cjs +1251 -0
- package/dist/motion.cjs.map +1 -0
- package/dist/motion.d.cts +79 -0
- package/dist/motion.d.ts +79 -0
- package/dist/motion.js +1092 -0
- package/dist/motion.js.map +1 -0
- package/package.json +19 -4
- package/dist/chunk-7ES63LA7.js.map +0 -1
- package/dist/chunk-BXRMVHNT.js.map +0 -1
- package/dist/chunk-QY5T4DPA.js.map +0 -1
|
@@ -135,7 +135,7 @@ function recordWithoutAffectingHost(record) {
|
|
|
135
135
|
} catch {
|
|
136
136
|
}
|
|
137
137
|
}
|
|
138
|
-
function createDataFlowRuntime(config, target = globalThis) {
|
|
138
|
+
function createDataFlowRuntime(config, target = globalThis, policy = {}) {
|
|
139
139
|
const componentRegistry = /* @__PURE__ */ new WeakMap();
|
|
140
140
|
const xhrMetadata = /* @__PURE__ */ new WeakMap();
|
|
141
141
|
const store = createRingStore(config.limits, target);
|
|
@@ -167,7 +167,11 @@ function createDataFlowRuntime(config, target = globalThis) {
|
|
|
167
167
|
if (isSpotPatchInternalUrl(
|
|
168
168
|
rawUrl,
|
|
169
169
|
target.location?.href ?? "http://spotpatch.invalid/"
|
|
170
|
-
)
|
|
170
|
+
) || policy.shouldObserveFetch?.(
|
|
171
|
+
input,
|
|
172
|
+
init,
|
|
173
|
+
target.location?.href ?? "http://spotpatch.invalid/"
|
|
174
|
+
) === false) {
|
|
171
175
|
return;
|
|
172
176
|
}
|
|
173
177
|
store.add(
|
|
@@ -223,7 +227,10 @@ function createDataFlowRuntime(config, target = globalThis) {
|
|
|
223
227
|
if (metadata === void 0 || isSpotPatchInternalUrl(
|
|
224
228
|
metadata.url,
|
|
225
229
|
target.location?.href ?? "http://spotpatch.invalid/"
|
|
226
|
-
)
|
|
230
|
+
) || policy.shouldObserveXhr?.(
|
|
231
|
+
metadata.url,
|
|
232
|
+
target.location?.href ?? "http://spotpatch.invalid/"
|
|
233
|
+
) === false) {
|
|
227
234
|
return;
|
|
228
235
|
}
|
|
229
236
|
const frame = currentRequestFrame;
|
|
@@ -397,9 +404,9 @@ function createDataFlowRuntime(config, target = globalThis) {
|
|
|
397
404
|
});
|
|
398
405
|
return runtime;
|
|
399
406
|
}
|
|
400
|
-
function installDataFlowPrelude(config, target = globalThis) {
|
|
407
|
+
function installDataFlowPrelude(config, target = globalThis, policy = {}) {
|
|
401
408
|
if (!config.enabled) return void 0;
|
|
402
|
-
const runtime = target[RUNTIME_KEY] ?? createDataFlowRuntime(config, target);
|
|
409
|
+
const runtime = target[RUNTIME_KEY] ?? createDataFlowRuntime(config, target, policy);
|
|
403
410
|
target[RUNTIME_KEY] = runtime;
|
|
404
411
|
return runtime;
|
|
405
412
|
}
|
|
@@ -549,4 +556,4 @@ export {
|
|
|
549
556
|
mergeComponentDataFlowReport,
|
|
550
557
|
mergePageDataFlowReport
|
|
551
558
|
};
|
|
552
|
-
//# sourceMappingURL=chunk-
|
|
559
|
+
//# sourceMappingURL=chunk-2WA6XVA4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/data-flow/data-flow-runtime.ts","../src/data-flow/report-merger.ts"],"sourcesContent":["import {\n DATA_FLOW_SCHEMA_VERSION,\n DATA_FLOW_URL_QUERY_KEY_LIMIT,\n SPOTPATCH_API_BASE,\n type NetworkObservation,\n type RuntimeDataFlowConfig,\n type RuntimeDataFlowLimits,\n type SanitizedObservedUrl,\n} from \"@spotpatch/shared/data-flow-runtime\";\n\nexport interface DataFlowComponentRegistration {\n readonly componentSourceId: string;\n readonly sourceVersion: string;\n}\n\nexport interface DataFlowInvocationToken {\n readonly invocationId: string;\n readonly componentSourceId: string;\n readonly triggerCallsiteId: string;\n readonly sourceVersion: string;\n}\n\nexport interface DataFlowRequestFrame {\n readonly requestCallsiteId: string;\n readonly sourceVersion: string;\n readonly invocationToken?: DataFlowInvocationToken;\n}\n\nexport interface DataFlowTriggerMetadata {\n readonly componentSourceId: string;\n readonly triggerCallsiteId: string;\n readonly sourceVersion: string;\n}\n\nexport interface DataFlowRequestMetadata {\n readonly requestCallsiteId: string;\n readonly sourceVersion: string;\n}\n\nexport interface DataFlowRuntime {\n readonly beginInvocation: (\n metadata: DataFlowTriggerMetadata,\n ) => DataFlowInvocationToken;\n readonly bindInvocation: <Arguments extends readonly unknown[], Result>(\n token: DataFlowInvocationToken | undefined,\n callback: (...args: Arguments) => Result,\n ) => (...args: Arguments) => Result;\n readonly bindTrigger: <Callback>(\n metadata: DataFlowTriggerMetadata,\n callback: Callback,\n ) => Callback;\n readonly captureInvocation: () => DataFlowInvocationToken | undefined;\n readonly clear: () => void;\n readonly createTrpcLink: () => DataFlowTrpcLink;\n readonly dispose: () => void;\n readonly getComponentRegistration: (\n component: object,\n ) => DataFlowComponentRegistration | undefined;\n readonly getCurrentRequestFrame: () => DataFlowRequestFrame | undefined;\n readonly observations: () => readonly NetworkObservation[];\n readonly updateRoute: (routeKey: string) => void;\n readonly registerComponent: (\n component: object,\n componentSourceId: string,\n sourceVersion: string,\n ) => void;\n readonly withInvocation: <Result>(\n token: DataFlowInvocationToken | undefined,\n callback: () => Result,\n ) => Result;\n readonly withRequestFrame: <Result>(\n token: DataFlowInvocationToken | undefined,\n metadata: DataFlowRequestMetadata,\n callback: () => Result,\n ) => Result;\n}\n\nexport interface DataFlowObservationPolicy {\n readonly shouldObserveFetch?: (\n input: RequestInfo | URL,\n init: RequestInit | undefined,\n baseUrl: string,\n ) => boolean;\n readonly shouldObserveXhr?: (url: string, baseUrl: string) => boolean;\n}\n\nexport interface DataFlowTrpcOperation {\n readonly path: unknown;\n readonly type: unknown;\n}\n\nexport interface DataFlowTrpcLinkOptions<\n Operation extends DataFlowTrpcOperation,\n Result,\n> {\n readonly next: (operation: Operation) => Result;\n readonly op: Operation;\n}\n\nexport type DataFlowTrpcLink = (\n runtime: unknown,\n) => <Operation extends DataFlowTrpcOperation, Result>(\n options: DataFlowTrpcLinkOptions<Operation, Result>,\n) => Result;\n\ninterface DataFlowGlobal {\n readonly fetch?: typeof globalThis.fetch;\n readonly location?: Location;\n readonly performance?: Performance;\n readonly XMLHttpRequest?: typeof globalThis.XMLHttpRequest;\n}\n\ninterface MutableDataFlowGlobal extends DataFlowGlobal {\n fetch?: typeof globalThis.fetch;\n}\n\ninterface XhrMetadata {\n readonly method: string;\n readonly url: string;\n}\n\ninterface RingEntry {\n readonly bytes: number;\n readonly observation: NetworkObservation;\n readonly recordedAt: number;\n}\n\nconst RUNTIME_KEY: unique symbol = Symbol.for(\n \"spotpatch.data-flow.runtime.v1\",\n) as never;\nconst REACT_MEMO_TYPE = Symbol.for(\"react.memo\");\nconst REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\");\n\ntype DataFlowRuntimeStore = Partial<Record<symbol, DataFlowRuntime>>;\ntype GlobalWithDataFlow = MutableDataFlowGlobal & DataFlowRuntimeStore;\n\nfunction positiveNow(target: DataFlowGlobal): number {\n return target.performance?.now() ?? Date.now();\n}\n\nfunction createOpaqueSequence(prefix: string): () => string {\n let sequence = 0;\n const randomPrefix = (() => {\n try {\n const bytes = new Uint8Array(8);\n globalThis.crypto.getRandomValues(bytes);\n return Array.from(bytes, (value) => value.toString(36).padStart(2, \"0\")).join(\"\");\n } catch {\n return \"local\";\n }\n })();\n\n return () => {\n sequence += 1;\n return `${prefix}_${randomPrefix}_${sequence.toString(36)}`;\n };\n}\n\nfunction freezeUrl(value: string, baseUrl: string): SanitizedObservedUrl {\n try {\n const url = new URL(value, baseUrl);\n return Object.freeze({\n origin: url.origin,\n pathname: url.pathname,\n queryKeys: Object.freeze(\n [...new Set(url.searchParams.keys())]\n .sort()\n .slice(0, DATA_FLOW_URL_QUERY_KEY_LIMIT),\n ),\n });\n } catch {\n return Object.freeze({\n pathname: value.split(/[?#]/u, 1)[0] ?? \"{invalid}\",\n queryKeys: Object.freeze([]),\n });\n }\n}\n\nfunction readFetchUrl(input: RequestInfo | URL): string {\n if (typeof input === \"string\") return input;\n if (input instanceof URL) return input.toString();\n return input.url;\n}\n\nfunction readFetchMethod(input: RequestInfo | URL, init?: RequestInit): string {\n if (init?.method !== undefined) return init.method.toUpperCase();\n return typeof Request !== \"undefined\" && input instanceof Request\n ? input.method.toUpperCase()\n : \"GET\";\n}\n\nfunction isSpotPatchInternalUrl(value: string, baseUrl: string): boolean {\n try {\n const pathname = new URL(value, baseUrl).pathname;\n return (\n pathname === SPOTPATCH_API_BASE || pathname.startsWith(`${SPOTPATCH_API_BASE}/`)\n );\n } catch {\n return false;\n }\n}\n\nfunction approximateBytes(value: unknown): number {\n return new TextEncoder().encode(JSON.stringify(value)).byteLength;\n}\n\nfunction createRingStore(\n limits: RuntimeDataFlowLimits,\n target: DataFlowGlobal,\n): Readonly<{\n add: (observation: NetworkObservation) => void;\n clear: () => void;\n values: () => readonly NetworkObservation[];\n}> {\n const entries: RingEntry[] = [];\n let totalBytes = 0;\n\n function removeExpired(now: number): void {\n while (\n entries[0] !== undefined &&\n now - entries[0].recordedAt > limits.observationTtlMs\n ) {\n const removed = entries.shift();\n if (removed !== undefined) totalBytes -= removed.bytes;\n }\n }\n\n return Object.freeze({\n add(observation): void {\n const now = positiveNow(target);\n removeExpired(now);\n const bytes = approximateBytes(observation);\n if (bytes > limits.observationMaxBytes) return;\n entries.push(Object.freeze({ bytes, observation, recordedAt: now }));\n totalBytes += bytes;\n\n while (\n entries.length > limits.observationMaxEntries ||\n totalBytes > limits.observationMaxBytes\n ) {\n const removed = entries.shift();\n if (removed !== undefined) totalBytes -= removed.bytes;\n }\n },\n clear(): void {\n entries.length = 0;\n totalBytes = 0;\n },\n values(): readonly NetworkObservation[] {\n removeExpired(positiveNow(target));\n return Object.freeze(entries.map(({ observation }) => observation));\n },\n });\n}\n\nfunction ownPropertyDescriptor(\n target: object,\n key: PropertyKey,\n): PropertyDescriptor | undefined {\n try {\n return Object.getOwnPropertyDescriptor(target, key);\n } catch {\n return undefined;\n }\n}\n\nfunction nestedReactWrapperComponent(candidate: object): object | undefined {\n const marker: unknown = ownPropertyDescriptor(candidate, \"$$typeof\")?.value;\n const key =\n marker === REACT_MEMO_TYPE\n ? \"type\"\n : marker === REACT_FORWARD_REF_TYPE\n ? \"render\"\n : undefined;\n if (key === undefined) return undefined;\n const nested: unknown = ownPropertyDescriptor(candidate, key)?.value;\n return (typeof nested === \"object\" && nested !== null) || typeof nested === \"function\"\n ? nested\n : undefined;\n}\n\nfunction installWritableDataProperty(\n target: object,\n key: PropertyKey,\n replacement: object,\n original: PropertyDescriptor | undefined = ownPropertyDescriptor(target, key),\n): (() => void) | undefined {\n if (original === undefined || !(\"value\" in original) || !original.writable) {\n return undefined;\n }\n\n try {\n Object.defineProperty(target, key, { ...original, value: replacement });\n } catch {\n return undefined;\n }\n\n return (): void => {\n try {\n if (ownPropertyDescriptor(target, key)?.value === replacement) {\n Object.defineProperty(target, key, original);\n }\n } catch {\n // A host or later wrapper can make the property non-configurable.\n }\n };\n}\n\nfunction recordWithoutAffectingHost(record: () => void): void {\n try {\n record();\n } catch {\n // Observation is optional; the host transport result is authoritative.\n }\n}\n\nexport function createDataFlowRuntime(\n config: RuntimeDataFlowConfig,\n target: MutableDataFlowGlobal = globalThis,\n policy: DataFlowObservationPolicy = {},\n): DataFlowRuntime {\n const componentRegistry = new WeakMap<object, DataFlowComponentRegistration>();\n const xhrMetadata = new WeakMap<object, XhrMetadata>();\n const store = createRingStore(config.limits, target);\n const nextInvocationId = createOpaqueSequence(\"invocation\");\n const nextObservationId = createOpaqueSequence(\"observation\");\n const pageEpoch = createOpaqueSequence(\"page\")();\n const nextRouteEpoch = createOpaqueSequence(\"route\");\n let routeEpoch = nextRouteEpoch();\n let routeKey: string | undefined;\n let currentInvocation: DataFlowInvocationToken | undefined;\n let currentRequestFrame: DataFlowRequestFrame | undefined;\n let disposed = false;\n\n const originalFetch = (() => {\n try {\n return target.fetch;\n } catch {\n return undefined;\n }\n })();\n function spotPatchFetch(\n this: typeof globalThis,\n input: RequestInfo | URL,\n init?: RequestInit,\n ): Promise<Response> {\n if (originalFetch === undefined) {\n throw new TypeError(\"Fetch is unavailable.\");\n }\n const result = Reflect.apply(originalFetch, this, [input, init]);\n recordWithoutAffectingHost(() => {\n const frame = currentRequestFrame;\n const token = frame?.invocationToken;\n const rawUrl = readFetchUrl(input);\n if (\n isSpotPatchInternalUrl(\n rawUrl,\n target.location?.href ?? \"http://spotpatch.invalid/\",\n ) ||\n policy.shouldObserveFetch?.(\n input,\n init,\n target.location?.href ?? \"http://spotpatch.invalid/\",\n ) === false\n ) {\n return;\n }\n store.add(\n Object.freeze({\n schemaVersion: DATA_FLOW_SCHEMA_VERSION,\n id: nextObservationId(),\n pageEpoch,\n routeEpoch,\n ...(frame === undefined\n ? {}\n : {\n requestCallsiteId: frame.requestCallsiteId,\n sourceVersion: frame.sourceVersion,\n }),\n ...(token === undefined\n ? {}\n : {\n invocationId: token.invocationId,\n componentSourceId: token.componentSourceId,\n triggerCallsiteId: token.triggerCallsiteId,\n }),\n transport: \"fetch\",\n method: readFetchMethod(input, init),\n url: freezeUrl(rawUrl, target.location?.href ?? \"http://spotpatch.invalid/\"),\n outcome: \"dispatched\",\n freshness: \"current\",\n diagnosticIds: Object.freeze([]),\n }),\n );\n });\n return result;\n }\n\n const restoreFetch =\n originalFetch === undefined\n ? undefined\n : installWritableDataProperty(target, \"fetch\", spotPatchFetch);\n\n const xhrPrototype = (() => {\n try {\n return target.XMLHttpRequest?.prototype;\n } catch {\n return undefined;\n }\n })();\n const originalOpenDescriptor =\n xhrPrototype === undefined\n ? undefined\n : ownPropertyDescriptor(xhrPrototype, \"open\");\n const originalSendDescriptor =\n xhrPrototype === undefined\n ? undefined\n : ownPropertyDescriptor(xhrPrototype, \"send\");\n\n function spotPatchOpen(\n this: XMLHttpRequest,\n method: string,\n url: string | URL,\n ...rest: readonly unknown[]\n ): void {\n const original: unknown = originalOpenDescriptor?.value;\n if (typeof original === \"function\") {\n Reflect.apply(original, this, [method, url, ...rest]);\n }\n recordWithoutAffectingHost(() => {\n xhrMetadata.set(this, Object.freeze({ method, url: String(url) }));\n });\n }\n\n function spotPatchSend(\n this: XMLHttpRequest,\n body?: Document | XMLHttpRequestBodyInit | null,\n ): void {\n const original: unknown = originalSendDescriptor?.value;\n if (typeof original === \"function\") Reflect.apply(original, this, [body]);\n recordWithoutAffectingHost(() => {\n const metadata = xhrMetadata.get(this);\n if (\n metadata === undefined ||\n isSpotPatchInternalUrl(\n metadata.url,\n target.location?.href ?? \"http://spotpatch.invalid/\",\n ) ||\n policy.shouldObserveXhr?.(\n metadata.url,\n target.location?.href ?? \"http://spotpatch.invalid/\",\n ) === false\n ) {\n return;\n }\n const frame = currentRequestFrame;\n const token = frame?.invocationToken;\n store.add(\n Object.freeze({\n schemaVersion: DATA_FLOW_SCHEMA_VERSION,\n id: nextObservationId(),\n pageEpoch,\n routeEpoch,\n ...(frame === undefined\n ? {}\n : {\n requestCallsiteId: frame.requestCallsiteId,\n sourceVersion: frame.sourceVersion,\n }),\n ...(token === undefined\n ? {}\n : {\n invocationId: token.invocationId,\n componentSourceId: token.componentSourceId,\n triggerCallsiteId: token.triggerCallsiteId,\n }),\n transport: \"xhr\",\n method: metadata.method.toUpperCase(),\n url: freezeUrl(\n metadata.url,\n target.location?.href ?? \"http://spotpatch.invalid/\",\n ),\n outcome: \"dispatched\",\n freshness: \"current\",\n diagnosticIds: Object.freeze([]),\n }),\n );\n });\n }\n\n const restoreXhrOpen =\n xhrPrototype === undefined || typeof originalOpenDescriptor?.value !== \"function\"\n ? undefined\n : installWritableDataProperty(\n xhrPrototype,\n \"open\",\n spotPatchOpen,\n originalOpenDescriptor,\n );\n const restoreXhrSend =\n xhrPrototype === undefined || typeof originalSendDescriptor?.value !== \"function\"\n ? undefined\n : installWritableDataProperty(\n xhrPrototype,\n \"send\",\n spotPatchSend,\n originalSendDescriptor,\n );\n\n const runtime: DataFlowRuntime = Object.freeze({\n beginInvocation(metadata: DataFlowTriggerMetadata): DataFlowInvocationToken {\n return Object.freeze({\n invocationId: nextInvocationId(),\n componentSourceId: metadata.componentSourceId,\n triggerCallsiteId: metadata.triggerCallsiteId,\n sourceVersion: metadata.sourceVersion,\n });\n },\n bindInvocation<Arguments extends readonly unknown[], Result>(\n token: DataFlowInvocationToken | undefined,\n callback: (...args: Arguments) => Result,\n ): (...args: Arguments) => Result {\n return function boundInvocation(this: unknown, ...args: Arguments): Result {\n return runtime.withInvocation(token, () => Reflect.apply(callback, this, args));\n };\n },\n bindTrigger<Callback>(\n metadata: DataFlowTriggerMetadata,\n callback: Callback,\n ): Callback {\n if (typeof callback !== \"function\") return callback;\n const callable = callback as (...args: readonly unknown[]) => unknown;\n return function boundTrigger(this: unknown, ...args: readonly unknown[]) {\n const token = runtime.beginInvocation(metadata);\n return runtime.withInvocation(token, () => Reflect.apply(callable, this, args));\n } as Callback;\n },\n captureInvocation: () => currentInvocation,\n clear: store.clear,\n createTrpcLink(): DataFlowTrpcLink {\n return () =>\n <Operation extends DataFlowTrpcOperation, Result>(\n options: DataFlowTrpcLinkOptions<Operation, Result>,\n ): Result => {\n recordWithoutAffectingHost(() => {\n const operation = options.op.path;\n const operationType = options.op.type;\n if (\n typeof operation !== \"string\" ||\n operation.length === 0 ||\n operation.length > 512 ||\n (operationType !== \"query\" &&\n operationType !== \"mutation\" &&\n operationType !== \"subscription\")\n ) {\n return;\n }\n const frame = currentRequestFrame;\n const token = frame?.invocationToken;\n store.add(\n Object.freeze({\n schemaVersion: DATA_FLOW_SCHEMA_VERSION,\n id: nextObservationId(),\n pageEpoch,\n routeEpoch,\n ...(frame === undefined\n ? {}\n : {\n requestCallsiteId: frame.requestCallsiteId,\n sourceVersion: frame.sourceVersion,\n }),\n ...(token === undefined\n ? {}\n : {\n invocationId: token.invocationId,\n componentSourceId: token.componentSourceId,\n triggerCallsiteId: token.triggerCallsiteId,\n }),\n transport: \"trpc\",\n method: operationType.toUpperCase(),\n operation,\n url: Object.freeze({\n pathname: operation,\n queryKeys: Object.freeze([]),\n }),\n outcome: \"dispatched\",\n freshness: \"current\",\n diagnosticIds: Object.freeze([]),\n }),\n );\n });\n return options.next(options.op);\n };\n },\n dispose(): void {\n if (disposed) return;\n disposed = true;\n store.clear();\n restoreFetch?.();\n restoreXhrOpen?.();\n restoreXhrSend?.();\n },\n getComponentRegistration: (component: object) => componentRegistry.get(component),\n getCurrentRequestFrame: () => currentRequestFrame,\n observations: () =>\n Object.freeze(\n store\n .values()\n .map((observation) =>\n observation.routeEpoch === routeEpoch\n ? observation\n : Object.freeze({ ...observation, freshness: \"stale-route\" as const }),\n ),\n ),\n registerComponent(\n component: object,\n componentSourceId: string,\n registeredSourceVersion: string,\n ): void {\n const registration = Object.freeze({\n componentSourceId,\n sourceVersion: registeredSourceVersion,\n });\n const pending = [component];\n const registered = new Set<object>();\n while (pending.length > 0) {\n const candidate = pending.pop();\n if (candidate === undefined || registered.has(candidate)) continue;\n registered.add(candidate);\n componentRegistry.set(candidate, registration);\n\n const nested = nestedReactWrapperComponent(candidate);\n if (nested !== undefined) pending.push(nested);\n }\n },\n updateRoute(nextRouteKey: string): void {\n if (routeKey === undefined) {\n routeKey = nextRouteKey;\n } else if (routeKey !== nextRouteKey) {\n routeKey = nextRouteKey;\n routeEpoch = nextRouteEpoch();\n }\n },\n withInvocation<Result>(\n token: DataFlowInvocationToken | undefined,\n callback: () => Result,\n ): Result {\n const parent = currentInvocation;\n currentInvocation = token;\n try {\n return callback();\n } finally {\n currentInvocation = parent;\n }\n },\n withRequestFrame<Result>(\n token: DataFlowInvocationToken | undefined,\n metadata: DataFlowRequestMetadata,\n callback: () => Result,\n ): Result {\n const parent = currentRequestFrame;\n currentRequestFrame = Object.freeze({\n requestCallsiteId: metadata.requestCallsiteId,\n sourceVersion: metadata.sourceVersion,\n ...(token === undefined ? {} : { invocationToken: token }),\n });\n try {\n return callback();\n } finally {\n currentRequestFrame = parent;\n }\n },\n });\n\n return runtime;\n}\n\nexport function installDataFlowPrelude(\n config: RuntimeDataFlowConfig,\n target: GlobalWithDataFlow = globalThis,\n policy: DataFlowObservationPolicy = {},\n): DataFlowRuntime | undefined {\n if (!config.enabled) return undefined;\n const runtime = target[RUNTIME_KEY] ?? createDataFlowRuntime(config, target, policy);\n target[RUNTIME_KEY] = runtime;\n return runtime;\n}\n\nexport function getDataFlowRuntime(\n target: GlobalWithDataFlow = globalThis,\n): DataFlowRuntime | undefined {\n return target[RUNTIME_KEY];\n}\n","import {\n isSensitiveName,\n limitDataFlowReportCollections,\n type ComponentDataFlowReport,\n type DataDependency,\n type EvidenceRef,\n type NetworkObservation,\n type PageDataFlowReport,\n} from \"@spotpatch/shared\";\n\nfunction observationMatchesDependency(\n observation: NetworkObservation,\n dependency: DataDependency,\n): boolean {\n const origin = dependency.origin;\n const transportMatches =\n dependency.kind === \"rpc\"\n ? observation.transport === \"trpc\" &&\n dependency.operation !== undefined &&\n observation.operation === dependency.operation\n : dependency.kind === \"http\"\n ? observation.transport === \"fetch\" || observation.transport === \"xhr\"\n : false;\n if (\n !transportMatches ||\n observation.freshness !== \"current\" ||\n origin === undefined ||\n observation.requestCallsiteId !== origin.requestCallsiteId ||\n observation.sourceVersion !== origin.sourceVersion ||\n (dependency.method !== undefined &&\n observation.method.toUpperCase() !== dependency.method.toUpperCase()) ||\n (dependency.url !== undefined &&\n observation.url.pathname !== dependency.url.pathname) ||\n (dependency.url?.origin !== undefined &&\n observation.url.origin !== dependency.url.origin) ||\n (origin.componentSourceId !== undefined &&\n observation.componentSourceId !== undefined &&\n observation.componentSourceId !== origin.componentSourceId) ||\n (origin.triggerCallsiteId !== undefined &&\n observation.triggerCallsiteId !== undefined &&\n observation.triggerCallsiteId !== origin.triggerCallsiteId)\n ) {\n return false;\n }\n\n return (\n dependency.association !== \"transitive\" ||\n (observation.componentSourceId === origin.componentSourceId &&\n observation.triggerCallsiteId === origin.triggerCallsiteId)\n );\n}\n\nfunction runtimeEvidence(observation: NetworkObservation): EvidenceRef {\n return Object.freeze({\n id: observation.id,\n kind: \"runtime-observation\",\n summaryKey: \"dataFlow.evidence.runtimeDispatch\",\n });\n}\n\nfunction mergeDependencies(\n dependencies: readonly DataDependency[],\n observations: readonly NetworkObservation[],\n): Readonly<{\n dependencies: readonly DataDependency[];\n matchedObservationIds: ReadonlySet<string>;\n}> {\n const matchedObservationIds = new Set<string>();\n const merged = dependencies.map((dependency) => {\n const matches = observations.filter((observation) =>\n observationMatchesDependency(observation, dependency),\n );\n for (const observation of matches) matchedObservationIds.add(observation.id);\n if (matches.length === 0) return dependency;\n const observedOrigins = [\n ...new Set(\n matches.flatMap(({ url }) => (url.origin === undefined ? [] : [url.origin])),\n ),\n ];\n const observedOrigin =\n observedOrigins.length === 1 ? observedOrigins[0] : undefined;\n return Object.freeze({\n ...dependency,\n ...(dependency.url === undefined ||\n dependency.url.origin !== undefined ||\n observedOrigin === undefined\n ? {}\n : {\n url: Object.freeze({\n ...dependency.url,\n origin: observedOrigin,\n }),\n }),\n execution: \"observed\" as const,\n observationIds: Object.freeze([\n ...new Set([...dependency.observationIds, ...matches.map(({ id }) => id)]),\n ]),\n evidenceIds: Object.freeze([\n ...new Set([...dependency.evidenceIds, ...matches.map(({ id }) => id)]),\n ]),\n });\n });\n return Object.freeze({\n dependencies: Object.freeze(merged),\n matchedObservationIds,\n });\n}\n\nfunction appendRuntimeEvidence(\n evidence: readonly EvidenceRef[],\n observations: readonly NetworkObservation[],\n matchedIds: ReadonlySet<string>,\n): readonly EvidenceRef[] {\n const existing = new Set(evidence.map(({ id }) => id));\n return Object.freeze([\n ...evidence,\n ...observations.flatMap((observation) =>\n matchedIds.has(observation.id) && !existing.has(observation.id)\n ? [runtimeEvidence(observation)]\n : [],\n ),\n ]);\n}\n\nexport function mergeComponentDataFlowReport(\n report: ComponentDataFlowReport,\n observations: readonly NetworkObservation[],\n): ComponentDataFlowReport {\n const componentObservations = observations.filter(\n (observation) =>\n observation.componentSourceId === undefined ||\n observation.componentSourceId === report.component.componentSourceId,\n );\n const merged = mergeDependencies(report.dependencies, componentObservations);\n return limitDataFlowReportCollections(\n Object.freeze({\n ...report,\n dependencies: merged.dependencies,\n evidence: appendRuntimeEvidence(\n report.evidence,\n componentObservations,\n merged.matchedObservationIds,\n ),\n }),\n { mode: \"observation\" },\n );\n}\n\nfunction unassignedDependency(observation: NetworkObservation): DataDependency {\n const isRpc = observation.transport === \"trpc\";\n return Object.freeze({\n id: observation.id,\n kind: isRpc ? \"rpc\" : \"http\",\n direction:\n observation.method === \"GET\" ||\n observation.method === \"HEAD\" ||\n observation.method === \"QUERY\" ||\n observation.method === \"SUBSCRIPTION\"\n ? \"read\"\n : \"write\",\n execution: \"observed\",\n proof: \"unavailable\",\n association: \"unassigned\",\n method: observation.method,\n ...(isRpc\n ? observation.operation === undefined\n ? {}\n : { operation: observation.operation }\n : { url: observation.url }),\n parameters: Object.freeze(\n (isRpc ? [] : observation.url.queryKeys).map((path) =>\n Object.freeze({\n path,\n position: \"query\" as const,\n sensitive: isSensitiveName(path),\n valueState: \"not-collected\" as const,\n evidenceIds: Object.freeze([observation.id]),\n }),\n ),\n ),\n response: Object.freeze({\n consumedFields: Object.freeze([]),\n }),\n suppliedBindings: Object.freeze([]),\n locationIds: Object.freeze([]),\n evidenceIds: Object.freeze([observation.id]),\n observationIds: Object.freeze([observation.id]),\n });\n}\n\nexport function mergePageDataFlowReport(\n report: PageDataFlowReport,\n observations: readonly NetworkObservation[],\n): PageDataFlowReport {\n const currentObservations = observations.filter(\n ({ freshness }) => freshness === \"current\",\n );\n const merged = mergeDependencies(report.dependencies, currentObservations);\n const unassigned = currentObservations\n .filter(({ id }) => !merged.matchedObservationIds.has(id))\n .map(unassignedDependency);\n const allObservationIds = new Set(currentObservations.map(({ id }) => id));\n return limitDataFlowReportCollections(\n Object.freeze({\n ...report,\n dependencies: Object.freeze([...merged.dependencies, ...unassigned]),\n evidence: appendRuntimeEvidence(\n report.evidence,\n currentObservations,\n allObservationIds,\n ),\n }),\n { mode: \"observation\" },\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/external-handoff-contract.ts"],"sourcesContent":["import type {\n DispatchSummary,\n ErrorCode,\n ExternalAgentControlStatus,\n ExternalAgentManagedResult,\n ExternalHandoffCapability,\n ExternalHandoffPublishResult,\n ExternalHandoffStatusResult,\n ExternalHandoffFramework,\n SpotAnnotation,\n SpotPatchLocale,\n} from \"@spotpatch/shared/external-handoff-browser\";\n\nexport interface ExternalHandoffPanel {\n readonly cancelManagedButton: HTMLButtonElement;\n readonly connectButton: HTMLButtonElement;\n readonly disconnectButton: HTMLButtonElement;\n readonly refreshButton: HTMLButtonElement;\n readonly root: HTMLElement;\n readonly sendButton: HTMLButtonElement;\n readonly styles: HTMLStyleElement;\n readonly confirmDisclosure: (annotation: SpotAnnotation) => Promise<boolean>;\n readonly dispose: () => void;\n readonly renderCapability: (capability: ExternalHandoffCapability) => void;\n readonly renderControlUnavailable: () => void;\n readonly renderControlStatus: (status: ExternalAgentControlStatus) => void;\n readonly renderError: (code?: ErrorCode, retryable?: boolean) => void;\n readonly renderPublishResult: (result: ExternalHandoffPublishResult) => void;\n readonly renderPublishing: () => void;\n readonly renderManagedResult: (result: ExternalAgentManagedResult) => void;\n readonly renderStatus: (result: ExternalHandoffStatusResult) => void;\n readonly resolveButton: HTMLButtonElement;\n readonly revokeButton: HTMLButtonElement;\n readonly setBusy: (busy: boolean) => void;\n readonly setControlBusy: (busy: boolean) => void;\n readonly setContextReady: (ready: boolean) => void;\n readonly setSelectionVisible: (visible: boolean) => void;\n}\n\nexport interface ExternalHandoffWorkflow {\n readonly cancelPending: () => void;\n readonly dispose: () => void;\n readonly mount: () => void;\n}\n\nexport interface ExternalHandoffExtension {\n readonly createPanel: (\n document: Document,\n framework: ExternalHandoffFramework,\n locale: () => SpotPatchLocale,\n sessionId: string,\n subscribeLocale: (listener: () => void) => () => void,\n onViewChange: () => void,\n onDispatchChange?: (dispatch: DispatchSummary | null) => void,\n onControlChange?: (status: ExternalAgentControlStatus | undefined) => void,\n ) => ExternalHandoffPanel;\n readonly createWorkflow: (\n fetch: typeof globalThis.fetch,\n panel: ExternalHandoffPanel,\n selectedAnnotation: () => SpotAnnotation | undefined,\n sessionToken: string,\n window: Window,\n ) => ExternalHandoffWorkflow;\n}\n\nconst EXTERNAL_HANDOFF_EXTENSION_KEY = Symbol.for(\"spotpatch.external-handoff.v1\");\ntype ExtensionStore = Partial<Record<symbol, ExternalHandoffExtension>>;\n\nexport function registerExternalHandoffExtension(\n extension: ExternalHandoffExtension,\n): void {\n (globalThis as ExtensionStore)[EXTERNAL_HANDOFF_EXTENSION_KEY] = extension;\n}\n\nexport function getExternalHandoffExtension(): ExternalHandoffExtension | undefined {\n return (globalThis as ExtensionStore)[EXTERNAL_HANDOFF_EXTENSION_KEY];\n}\n"],"mappings":";AAiEA,IAAM,iCAAiC,uBAAO,IAAI,+BAA+B;AAG1E,SAAS,iCACd,WACM;AACN,EAAC,WAA8B,8BAA8B,IAAI;AACnE;AAEO,SAAS,8BAAoE;AAClF,SAAQ,WAA8B,8BAA8B;AACtE;","names":[]}
|
|
@@ -4,6 +4,15 @@ var UI_Z_INDEX = Object.freeze({
|
|
|
4
4
|
highlight: 2147483646,
|
|
5
5
|
controls: 2147483647
|
|
6
6
|
});
|
|
7
|
+
var FLOATING_SURFACE_LAYOUT = Object.freeze({
|
|
8
|
+
compactInset: 8,
|
|
9
|
+
compactViewportWidth: 520,
|
|
10
|
+
desktopInset: 24,
|
|
11
|
+
dragActivationDistance: 6,
|
|
12
|
+
edgeSnapDistance: 20,
|
|
13
|
+
workbenchMaxHeight: 620,
|
|
14
|
+
workbenchMaxWidth: 460
|
|
15
|
+
});
|
|
7
16
|
|
|
8
17
|
// src/ui/dom.ts
|
|
9
18
|
function createMarkedElement(document, tagName) {
|
|
@@ -22,7 +31,8 @@ function createButton(document, label, className = "") {
|
|
|
22
31
|
export {
|
|
23
32
|
UI_MARKER_ATTRIBUTE,
|
|
24
33
|
UI_Z_INDEX,
|
|
34
|
+
FLOATING_SURFACE_LAYOUT,
|
|
25
35
|
createMarkedElement,
|
|
26
36
|
createButton
|
|
27
37
|
};
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
38
|
+
//# sourceMappingURL=chunk-P6X75LO5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/ui-constants.ts","../src/ui/dom.ts"],"sourcesContent":["export const UI_MARKER_ATTRIBUTE = \"data-spotpatch-ui\" as const;\n\nexport const UI_Z_INDEX = Object.freeze({\n highlight: 2_147_483_646,\n controls: 2_147_483_647,\n});\n\nexport const FLOATING_SURFACE_LAYOUT = Object.freeze({\n compactInset: 8,\n compactViewportWidth: 520,\n desktopInset: 24,\n dragActivationDistance: 6,\n edgeSnapDistance: 20,\n workbenchMaxHeight: 620,\n workbenchMaxWidth: 460,\n});\n","import { UI_MARKER_ATTRIBUTE } from \"./ui-constants.js\";\n\nexport function createMarkedElement<K extends keyof HTMLElementTagNameMap>(\n document: Document,\n tagName: K,\n): HTMLElementTagNameMap[K] {\n const element = document.createElement(tagName);\n element.setAttribute(UI_MARKER_ATTRIBUTE, \"\");\n return element;\n}\n\nexport function createButton(\n document: Document,\n label: string,\n className = \"\",\n): HTMLButtonElement {\n const button = createMarkedElement(document, \"button\");\n button.type = \"button\";\n button.className = className;\n button.textContent = label;\n return button;\n}\n"],"mappings":";AAAO,IAAM,sBAAsB;AAE5B,IAAM,aAAa,OAAO,OAAO;AAAA,EACtC,WAAW;AAAA,EACX,UAAU;AACZ,CAAC;AAEM,IAAM,0BAA0B,OAAO,OAAO;AAAA,EACnD,cAAc;AAAA,EACd,sBAAsB;AAAA,EACtB,cAAc;AAAA,EACd,wBAAwB;AAAA,EACxB,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,mBAAmB;AACrB,CAAC;;;ACbM,SAAS,oBACd,UACA,SAC0B;AAC1B,QAAM,UAAU,SAAS,cAAc,OAAO;AAC9C,UAAQ,aAAa,qBAAqB,EAAE;AAC5C,SAAO;AACT;AAEO,SAAS,aACd,UACA,OACA,YAAY,IACO;AACnB,QAAM,SAAS,oBAAoB,UAAU,QAAQ;AACrD,SAAO,OAAO;AACd,SAAO,YAAY;AACnB,SAAO,cAAc;AACrB,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// src/ui/motion-extension-contract.ts
|
|
2
|
+
var MOTION_EXTENSION_KEY = /* @__PURE__ */ Symbol.for("spotpatch.motion.v1");
|
|
3
|
+
function registerFloatingSurfaceMotionExtension(extension) {
|
|
4
|
+
globalThis[MOTION_EXTENSION_KEY] = extension;
|
|
5
|
+
}
|
|
6
|
+
function getFloatingSurfaceMotionExtension() {
|
|
7
|
+
return globalThis[MOTION_EXTENSION_KEY];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// src/ui/brand-mark-content.ts
|
|
11
|
+
var BRAND_MARK_CONTENT = `
|
|
12
|
+
<defs>
|
|
13
|
+
<linearGradient id="locator-gradient" x1="76" y1="92" x2="436" y2="374" gradientUnits="userSpaceOnUse">
|
|
14
|
+
<stop offset="0" stop-color="#B61CFF" />
|
|
15
|
+
<stop offset="0.38" stop-color="#6D35FF" />
|
|
16
|
+
<stop offset="0.72" stop-color="#168EFF" />
|
|
17
|
+
<stop offset="1" stop-color="#00D9E9" />
|
|
18
|
+
</linearGradient>
|
|
19
|
+
<linearGradient id="left-code-gradient" x1="165" y1="166" x2="236" y2="258" gradientUnits="userSpaceOnUse">
|
|
20
|
+
<stop stop-color="#A51EFF" />
|
|
21
|
+
<stop offset="1" stop-color="#653BFF" />
|
|
22
|
+
</linearGradient>
|
|
23
|
+
<linearGradient id="right-code-gradient" x1="276" y1="166" x2="347" y2="258" gradientUnits="userSpaceOnUse">
|
|
24
|
+
<stop stop-color="#158DFF" />
|
|
25
|
+
<stop offset="1" stop-color="#00D8E9" />
|
|
26
|
+
</linearGradient>
|
|
27
|
+
<linearGradient id="bolt-gradient" x1="270" y1="111" x2="252" y2="365" gradientUnits="userSpaceOnUse">
|
|
28
|
+
<stop stop-color="#6840FF" />
|
|
29
|
+
<stop offset="0.48" stop-color="#257BFF" />
|
|
30
|
+
<stop offset="1" stop-color="#00CBEF" />
|
|
31
|
+
</linearGradient>
|
|
32
|
+
</defs>
|
|
33
|
+
<path
|
|
34
|
+
fill="url(#locator-gradient)"
|
|
35
|
+
fill-rule="evenodd"
|
|
36
|
+
clip-rule="evenodd"
|
|
37
|
+
d="M256 52C345.47 52 418 124.53 418 214C418 267.55 391.98 316.24 354.04 348.02L256 468L157.96 348.02C120.02 316.24 94 267.55 94 214C94 124.53 166.53 52 256 52ZM256 88C186.41 88 130 144.41 130 214C130 258.2 152.76 297.08 187.2 319.57L256 403.8L324.8 319.57C359.24 297.08 382 258.2 382 214C382 144.41 325.59 88 256 88Z"
|
|
38
|
+
/>
|
|
39
|
+
<rect x="238" y="20" width="36" height="84" rx="4" fill="url(#locator-gradient)" />
|
|
40
|
+
<rect x="62" y="196" width="84" height="36" rx="4" fill="url(#locator-gradient)" />
|
|
41
|
+
<rect x="366" y="196" width="84" height="36" rx="4" fill="url(#locator-gradient)" />
|
|
42
|
+
<path
|
|
43
|
+
d="M213.5 160L158 211.5L213.5 263L238 236.5L211 211.5L238 186.5L213.5 160Z"
|
|
44
|
+
fill="url(#left-code-gradient)"
|
|
45
|
+
/>
|
|
46
|
+
<path
|
|
47
|
+
d="M298.5 160L354 211.5L298.5 263L274 236.5L301 211.5L274 186.5L298.5 160Z"
|
|
48
|
+
fill="url(#right-code-gradient)"
|
|
49
|
+
/>
|
|
50
|
+
<path
|
|
51
|
+
d="M283 108L232 212L266 253L238 369L302 237L267 198L283 108Z"
|
|
52
|
+
fill="url(#bolt-gradient)"
|
|
53
|
+
/>
|
|
54
|
+
`;
|
|
55
|
+
|
|
56
|
+
// src/ui/brand-mark.ts
|
|
57
|
+
var SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
58
|
+
function resolveBrandMarkContent(override) {
|
|
59
|
+
if (override !== void 0) {
|
|
60
|
+
return { content: override, viewBox: "0 0 512 512" };
|
|
61
|
+
}
|
|
62
|
+
const injected = typeof __SPOTPATCH_BRAND_MARK_CONTENT__ === "string" ? __SPOTPATCH_BRAND_MARK_CONTENT__ : void 0;
|
|
63
|
+
if (typeof injected === "string") {
|
|
64
|
+
return { content: injected, viewBox: "0 0 512 512" };
|
|
65
|
+
}
|
|
66
|
+
return true ? { content: BRAND_MARK_CONTENT, viewBox: "0 0 512 512" } : { content: FALLBACK_BRAND_MARK_CONTENT, viewBox: "0 0 1 1" };
|
|
67
|
+
}
|
|
68
|
+
function svgElement(document, tagName, attributes) {
|
|
69
|
+
const element = document.createElementNS(SVG_NAMESPACE, tagName);
|
|
70
|
+
for (const [name, value] of Object.entries(attributes)) {
|
|
71
|
+
element.setAttribute(name, value);
|
|
72
|
+
}
|
|
73
|
+
return element;
|
|
74
|
+
}
|
|
75
|
+
function namespaceSvgIds(svg, prefix) {
|
|
76
|
+
const safePrefix = prefix.replace(/[^a-zA-Z0-9_-]/gu, "-");
|
|
77
|
+
const ids = /* @__PURE__ */ new Map();
|
|
78
|
+
for (const element of svg.querySelectorAll("[id]")) {
|
|
79
|
+
const id = element.id;
|
|
80
|
+
const namespacedId = `${safePrefix}-${id}`;
|
|
81
|
+
ids.set(id, namespacedId);
|
|
82
|
+
element.id = namespacedId;
|
|
83
|
+
}
|
|
84
|
+
for (const element of [svg, ...svg.querySelectorAll("*")]) {
|
|
85
|
+
for (const attribute of [...element.attributes]) {
|
|
86
|
+
let value = attribute.value;
|
|
87
|
+
for (const [id, namespacedId] of ids) {
|
|
88
|
+
value = value.replaceAll(`url(#${id})`, `url(#${namespacedId})`);
|
|
89
|
+
if (value === `#${id}`) value = `#${namespacedId}`;
|
|
90
|
+
}
|
|
91
|
+
if (value !== attribute.value) element.setAttribute(attribute.name, value);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
function createBrandMark(document, content, idPrefix) {
|
|
96
|
+
const resolved = resolveBrandMarkContent(content);
|
|
97
|
+
const svg = svgElement(document, "svg", {
|
|
98
|
+
xmlns: SVG_NAMESPACE,
|
|
99
|
+
class: "spotpatch-brand-mark",
|
|
100
|
+
viewBox: resolved.viewBox,
|
|
101
|
+
"aria-hidden": "true",
|
|
102
|
+
focusable: "false"
|
|
103
|
+
});
|
|
104
|
+
svg.innerHTML = resolved.content;
|
|
105
|
+
if (idPrefix !== void 0) namespaceSvgIds(svg, idPrefix);
|
|
106
|
+
return svg;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export {
|
|
110
|
+
BRAND_MARK_CONTENT,
|
|
111
|
+
createBrandMark,
|
|
112
|
+
registerFloatingSurfaceMotionExtension,
|
|
113
|
+
getFloatingSurfaceMotionExtension
|
|
114
|
+
};
|
|
115
|
+
//# sourceMappingURL=chunk-P7W3F4UA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ui/motion-extension-contract.ts","../src/ui/brand-mark-content.ts","../src/ui/brand-mark.ts"],"sourcesContent":["export type FloatingSurfaceScene =\n | \"pill\"\n | \"capturing\"\n | \"planner\"\n | \"agent-charging\"\n | \"handoff\"\n | \"running\"\n | \"success\"\n | \"failed\";\n\nexport type FloatingSurfaceTone =\n \"neutral\" | \"capturing\" | \"ready\" | \"running\" | \"success\" | \"danger\";\n\nexport type ExecutionActivityKind =\n | \"prepare\"\n | \"dispatch\"\n | \"discover\"\n | \"search\"\n | \"read\"\n | \"patch\"\n | \"check\"\n | \"audit\"\n | \"apply\"\n | \"sync\"\n | \"unknown\";\n\nexport interface FloatingSurfaceActivity {\n readonly detail?: string;\n readonly key: string;\n readonly kind: ExecutionActivityKind;\n readonly label: string;\n readonly state: \"active\" | \"success\" | \"failure\" | \"info\";\n}\n\nexport interface FloatingSurfaceProjection {\n readonly action: string;\n readonly activity?: FloatingSurfaceActivity;\n readonly expandedAction?: string;\n readonly expandedHeadline?: string;\n readonly headline: string;\n readonly meta: string;\n readonly recentActivities: readonly FloatingSurfaceActivity[];\n readonly scene: FloatingSurfaceScene;\n readonly startedAt?: string;\n readonly tone: FloatingSurfaceTone;\n}\n\nexport interface ExecutionIslandElements {\n readonly action: HTMLElement;\n readonly actionOutgoing: HTMLElement;\n readonly content: HTMLElement;\n readonly headline: HTMLElement;\n readonly headlineOutgoing: HTMLElement;\n readonly logo: SVGSVGElement;\n readonly mark: HTMLElement;\n readonly meta: HTMLElement;\n readonly metaDot: HTMLElement;\n readonly metaLabel: HTMLElement;\n readonly more: HTMLElement;\n readonly recent: HTMLElement;\n readonly root: HTMLButtonElement;\n readonly sweep: HTMLElement;\n readonly timer: HTMLElement;\n}\n\nexport interface ExecutionIslandView {\n readonly canExpand: () => boolean;\n readonly dispose: () => void;\n readonly isExpanded: () => boolean;\n readonly render: (projection: FloatingSurfaceProjection) => void;\n readonly root: HTMLButtonElement;\n readonly setExpanded: (expanded: boolean) => void;\n}\n\nexport interface MotionExecutionIsland extends ExecutionIslandView {\n readonly elements: ExecutionIslandElements;\n}\n\nexport interface FloatingSurfaceMotionElements {\n readonly execution: ExecutionIslandElements;\n readonly pill: HTMLButtonElement;\n readonly planner: HTMLElement;\n readonly surface: HTMLElement;\n}\n\nexport interface FloatingSurfaceMotionController {\n readonly cancel: () => void;\n readonly dispatch: (source: HTMLElement, target: HTMLElement) => void;\n readonly dispose: () => void;\n readonly render: (\n projection: FloatingSurfaceProjection,\n renderContent: () => void,\n ) => void;\n readonly updateLayout: (updateContent: () => void) => void;\n}\n\nexport interface FloatingSurfaceMotionExtension {\n readonly createExecutionIsland: (document: Document) => MotionExecutionIsland;\n readonly createController: (\n document: Document,\n elements: FloatingSurfaceMotionElements,\n reconcile: () => void,\n ) => FloatingSurfaceMotionController;\n readonly createStyles: (document: Document) => HTMLStyleElement;\n}\n\nconst MOTION_EXTENSION_KEY = Symbol.for(\"spotpatch.motion.v1\");\ntype ExtensionStore = Partial<Record<symbol, FloatingSurfaceMotionExtension>>;\n\nexport function registerFloatingSurfaceMotionExtension(\n extension: FloatingSurfaceMotionExtension,\n): void {\n (globalThis as ExtensionStore)[MOTION_EXTENSION_KEY] = extension;\n}\n\nexport function getFloatingSurfaceMotionExtension():\n FloatingSurfaceMotionExtension | undefined {\n return (globalThis as ExtensionStore)[MOTION_EXTENSION_KEY];\n}\n","/**\n * Canonical SpotPatch mark from docs/assets/spotpatch-logo-mark.svg.\n *\n * The Vite development injector consumes this trusted asset separately from\n * the core browser bundle so the Runtime gzip budget remains enforceable.\n */\nexport const BRAND_MARK_CONTENT = `\n <defs>\n <linearGradient id=\"locator-gradient\" x1=\"76\" y1=\"92\" x2=\"436\" y2=\"374\" gradientUnits=\"userSpaceOnUse\">\n <stop offset=\"0\" stop-color=\"#B61CFF\" />\n <stop offset=\"0.38\" stop-color=\"#6D35FF\" />\n <stop offset=\"0.72\" stop-color=\"#168EFF\" />\n <stop offset=\"1\" stop-color=\"#00D9E9\" />\n </linearGradient>\n <linearGradient id=\"left-code-gradient\" x1=\"165\" y1=\"166\" x2=\"236\" y2=\"258\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#A51EFF\" />\n <stop offset=\"1\" stop-color=\"#653BFF\" />\n </linearGradient>\n <linearGradient id=\"right-code-gradient\" x1=\"276\" y1=\"166\" x2=\"347\" y2=\"258\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#158DFF\" />\n <stop offset=\"1\" stop-color=\"#00D8E9\" />\n </linearGradient>\n <linearGradient id=\"bolt-gradient\" x1=\"270\" y1=\"111\" x2=\"252\" y2=\"365\" gradientUnits=\"userSpaceOnUse\">\n <stop stop-color=\"#6840FF\" />\n <stop offset=\"0.48\" stop-color=\"#257BFF\" />\n <stop offset=\"1\" stop-color=\"#00CBEF\" />\n </linearGradient>\n </defs>\n <path\n fill=\"url(#locator-gradient)\"\n fill-rule=\"evenodd\"\n clip-rule=\"evenodd\"\n d=\"M256 52C345.47 52 418 124.53 418 214C418 267.55 391.98 316.24 354.04 348.02L256 468L157.96 348.02C120.02 316.24 94 267.55 94 214C94 124.53 166.53 52 256 52ZM256 88C186.41 88 130 144.41 130 214C130 258.2 152.76 297.08 187.2 319.57L256 403.8L324.8 319.57C359.24 297.08 382 258.2 382 214C382 144.41 325.59 88 256 88Z\"\n />\n <rect x=\"238\" y=\"20\" width=\"36\" height=\"84\" rx=\"4\" fill=\"url(#locator-gradient)\" />\n <rect x=\"62\" y=\"196\" width=\"84\" height=\"36\" rx=\"4\" fill=\"url(#locator-gradient)\" />\n <rect x=\"366\" y=\"196\" width=\"84\" height=\"36\" rx=\"4\" fill=\"url(#locator-gradient)\" />\n <path\n d=\"M213.5 160L158 211.5L213.5 263L238 236.5L211 211.5L238 186.5L213.5 160Z\"\n fill=\"url(#left-code-gradient)\"\n />\n <path\n d=\"M298.5 160L354 211.5L298.5 263L274 236.5L301 211.5L274 186.5L298.5 160Z\"\n fill=\"url(#right-code-gradient)\"\n />\n <path\n d=\"M283 108L232 212L266 253L238 369L302 237L267 198L283 108Z\"\n fill=\"url(#bolt-gradient)\"\n />\n`;\n","import { BRAND_MARK_CONTENT } from \"./brand-mark-content.js\";\n\nconst SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\ndeclare const __SPOTPATCH_INLINE_BRAND_MARK__: boolean;\ndeclare const __SPOTPATCH_BRAND_MARK_CONTENT__: string | undefined;\n\n/**\n * Deliberately empty fail-closed fallback for an invalid Vite injection.\n *\n * The browser bundle must not carry a second logo implementation: normal\n * Vite development injects BRAND_MARK_CONTENT lexically, while standalone\n * Runtime builds inline the canonical asset at compile time. Keeping this\n * branch empty preserves the bundle budget and prevents stale branding if a\n * host violates either build contract.\n */\nconst FALLBACK_BRAND_MARK_CONTENT = \"\";\n\nfunction resolveBrandMarkContent(override?: string): Readonly<{\n readonly content: string;\n readonly viewBox: string;\n}> {\n if (override !== undefined) {\n return { content: override, viewBox: \"0 0 512 512\" };\n }\n\n const injected =\n typeof __SPOTPATCH_BRAND_MARK_CONTENT__ === \"string\"\n ? __SPOTPATCH_BRAND_MARK_CONTENT__\n : undefined;\n if (typeof injected === \"string\") {\n return { content: injected, viewBox: \"0 0 512 512\" };\n }\n\n return __SPOTPATCH_INLINE_BRAND_MARK__\n ? { content: BRAND_MARK_CONTENT, viewBox: \"0 0 512 512\" }\n : { content: FALLBACK_BRAND_MARK_CONTENT, viewBox: \"0 0 1 1\" };\n}\n\nfunction svgElement<K extends keyof SVGElementTagNameMap>(\n document: Document,\n tagName: K,\n attributes: Readonly<Record<string, string>>,\n): SVGElementTagNameMap[K] {\n const element = document.createElementNS(SVG_NAMESPACE, tagName);\n\n for (const [name, value] of Object.entries(attributes)) {\n element.setAttribute(name, value);\n }\n\n return element;\n}\n\nfunction namespaceSvgIds(svg: SVGSVGElement, prefix: string): void {\n const safePrefix = prefix.replace(/[^a-zA-Z0-9_-]/gu, \"-\");\n const ids = new Map<string, string>();\n\n for (const element of svg.querySelectorAll(\"[id]\")) {\n const id = element.id;\n const namespacedId = `${safePrefix}-${id}`;\n ids.set(id, namespacedId);\n element.id = namespacedId;\n }\n\n for (const element of [svg, ...svg.querySelectorAll(\"*\")]) {\n for (const attribute of [...element.attributes]) {\n let value = attribute.value;\n for (const [id, namespacedId] of ids) {\n value = value.replaceAll(`url(#${id})`, `url(#${namespacedId})`);\n if (value === `#${id}`) value = `#${namespacedId}`;\n }\n if (value !== attribute.value) element.setAttribute(attribute.name, value);\n }\n }\n}\n\n/** Vector form of docs/assets/spotpatch-logo-mark.svg; safe to inline in Shadow DOM. */\nexport function createBrandMark(\n document: Document,\n content?: string,\n idPrefix?: string,\n): SVGSVGElement {\n const resolved = resolveBrandMarkContent(content);\n const svg = svgElement(document, \"svg\", {\n xmlns: SVG_NAMESPACE,\n class: \"spotpatch-brand-mark\",\n viewBox: resolved.viewBox,\n \"aria-hidden\": \"true\",\n focusable: \"false\",\n });\n svg.innerHTML = resolved.content;\n if (idPrefix !== undefined) namespaceSvgIds(svg, idPrefix);\n return svg;\n}\n"],"mappings":";AA0GA,IAAM,uBAAuB,uBAAO,IAAI,qBAAqB;AAGtD,SAAS,uCACd,WACM;AACN,EAAC,WAA8B,oBAAoB,IAAI;AACzD;AAEO,SAAS,oCAC6B;AAC3C,SAAQ,WAA8B,oBAAoB;AAC5D;;;AChHO,IAAM,qBAAqB;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;;;ACJlC,IAAM,gBAAgB;AAetB,SAAS,wBAAwB,UAG9B;AACD,MAAI,aAAa,QAAW;AAC1B,WAAO,EAAE,SAAS,UAAU,SAAS,cAAc;AAAA,EACrD;AAEA,QAAM,WACJ,OAAO,qCAAqC,WACxC,mCACA;AACN,MAAI,OAAO,aAAa,UAAU;AAChC,WAAO,EAAE,SAAS,UAAU,SAAS,cAAc;AAAA,EACrD;AAEA,SAAO,OACH,EAAE,SAAS,oBAAoB,SAAS,cAAc,IACtD,EAAE,SAAS,6BAA6B,SAAS,UAAU;AACjE;AAEA,SAAS,WACP,UACA,SACA,YACyB;AACzB,QAAM,UAAU,SAAS,gBAAgB,eAAe,OAAO;AAE/D,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AACtD,YAAQ,aAAa,MAAM,KAAK;AAAA,EAClC;AAEA,SAAO;AACT;AAEA,SAAS,gBAAgB,KAAoB,QAAsB;AACjE,QAAM,aAAa,OAAO,QAAQ,oBAAoB,GAAG;AACzD,QAAM,MAAM,oBAAI,IAAoB;AAEpC,aAAW,WAAW,IAAI,iBAAiB,MAAM,GAAG;AAClD,UAAM,KAAK,QAAQ;AACnB,UAAM,eAAe,GAAG,UAAU,IAAI,EAAE;AACxC,QAAI,IAAI,IAAI,YAAY;AACxB,YAAQ,KAAK;AAAA,EACf;AAEA,aAAW,WAAW,CAAC,KAAK,GAAG,IAAI,iBAAiB,GAAG,CAAC,GAAG;AACzD,eAAW,aAAa,CAAC,GAAG,QAAQ,UAAU,GAAG;AAC/C,UAAI,QAAQ,UAAU;AACtB,iBAAW,CAAC,IAAI,YAAY,KAAK,KAAK;AACpC,gBAAQ,MAAM,WAAW,QAAQ,EAAE,KAAK,QAAQ,YAAY,GAAG;AAC/D,YAAI,UAAU,IAAI,EAAE,GAAI,SAAQ,IAAI,YAAY;AAAA,MAClD;AACA,UAAI,UAAU,UAAU,MAAO,SAAQ,aAAa,UAAU,MAAM,KAAK;AAAA,IAC3E;AAAA,EACF;AACF;AAGO,SAAS,gBACd,UACA,SACA,UACe;AACf,QAAM,WAAW,wBAAwB,OAAO;AAChD,QAAM,MAAM,WAAW,UAAU,OAAO;AAAA,IACtC,OAAO;AAAA,IACP,OAAO;AAAA,IACP,SAAS,SAAS;AAAA,IAClB,eAAe;AAAA,IACf,WAAW;AAAA,EACb,CAAC;AACD,MAAI,YAAY,SAAS;AACzB,MAAI,aAAa,OAAW,iBAAgB,KAAK,QAAQ;AACzD,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=chunk-RZDOL5BT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/data-flow-panel.cjs
CHANGED
|
@@ -22,6 +22,7 @@ var data_flow_panel_entry_exports = {};
|
|
|
22
22
|
__export(data_flow_panel_entry_exports, {
|
|
23
23
|
createDataFlowPanel: () => createDataFlowPanel,
|
|
24
24
|
getDataFlowExtension: () => getDataFlowExtension,
|
|
25
|
+
installDataFlowPanelExtension: () => installDataFlowPanelExtension,
|
|
25
26
|
registerDataFlowExtension: () => registerDataFlowExtension
|
|
26
27
|
});
|
|
27
28
|
module.exports = __toCommonJS(data_flow_panel_entry_exports);
|
|
@@ -32,6 +33,15 @@ var UI_Z_INDEX = Object.freeze({
|
|
|
32
33
|
highlight: 2147483646,
|
|
33
34
|
controls: 2147483647
|
|
34
35
|
});
|
|
36
|
+
var FLOATING_SURFACE_LAYOUT = Object.freeze({
|
|
37
|
+
compactInset: 8,
|
|
38
|
+
compactViewportWidth: 520,
|
|
39
|
+
desktopInset: 24,
|
|
40
|
+
dragActivationDistance: 6,
|
|
41
|
+
edgeSnapDistance: 20,
|
|
42
|
+
workbenchMaxHeight: 620,
|
|
43
|
+
workbenchMaxWidth: 460
|
|
44
|
+
});
|
|
35
45
|
|
|
36
46
|
// src/ui/dom.ts
|
|
37
47
|
function createMarkedElement(document, tagName) {
|
|
@@ -324,10 +334,171 @@ function registerDataFlowExtension(extension, target = globalThis) {
|
|
|
324
334
|
function getDataFlowExtension(target = globalThis) {
|
|
325
335
|
return target[DATA_FLOW_EXTENSION_KEY];
|
|
326
336
|
}
|
|
337
|
+
|
|
338
|
+
// src/data-flow/data-flow-runtime.ts
|
|
339
|
+
var import_data_flow_runtime = require("@spotpatch/shared/data-flow-runtime");
|
|
340
|
+
var RUNTIME_KEY = /* @__PURE__ */ Symbol.for(
|
|
341
|
+
"spotpatch.data-flow.runtime.v1"
|
|
342
|
+
);
|
|
343
|
+
function getDataFlowRuntime(target = globalThis) {
|
|
344
|
+
return target[RUNTIME_KEY];
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// src/data-flow/report-merger.ts
|
|
348
|
+
var import_shared = require("@spotpatch/shared");
|
|
349
|
+
function observationMatchesDependency(observation, dependency) {
|
|
350
|
+
const origin = dependency.origin;
|
|
351
|
+
const transportMatches = dependency.kind === "rpc" ? observation.transport === "trpc" && dependency.operation !== void 0 && observation.operation === dependency.operation : dependency.kind === "http" ? observation.transport === "fetch" || observation.transport === "xhr" : false;
|
|
352
|
+
if (!transportMatches || observation.freshness !== "current" || origin === void 0 || observation.requestCallsiteId !== origin.requestCallsiteId || observation.sourceVersion !== origin.sourceVersion || dependency.method !== void 0 && observation.method.toUpperCase() !== dependency.method.toUpperCase() || dependency.url !== void 0 && observation.url.pathname !== dependency.url.pathname || dependency.url?.origin !== void 0 && observation.url.origin !== dependency.url.origin || origin.componentSourceId !== void 0 && observation.componentSourceId !== void 0 && observation.componentSourceId !== origin.componentSourceId || origin.triggerCallsiteId !== void 0 && observation.triggerCallsiteId !== void 0 && observation.triggerCallsiteId !== origin.triggerCallsiteId) {
|
|
353
|
+
return false;
|
|
354
|
+
}
|
|
355
|
+
return dependency.association !== "transitive" || observation.componentSourceId === origin.componentSourceId && observation.triggerCallsiteId === origin.triggerCallsiteId;
|
|
356
|
+
}
|
|
357
|
+
function runtimeEvidence(observation) {
|
|
358
|
+
return Object.freeze({
|
|
359
|
+
id: observation.id,
|
|
360
|
+
kind: "runtime-observation",
|
|
361
|
+
summaryKey: "dataFlow.evidence.runtimeDispatch"
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
function mergeDependencies(dependencies, observations) {
|
|
365
|
+
const matchedObservationIds = /* @__PURE__ */ new Set();
|
|
366
|
+
const merged = dependencies.map((dependency) => {
|
|
367
|
+
const matches = observations.filter(
|
|
368
|
+
(observation) => observationMatchesDependency(observation, dependency)
|
|
369
|
+
);
|
|
370
|
+
for (const observation of matches) matchedObservationIds.add(observation.id);
|
|
371
|
+
if (matches.length === 0) return dependency;
|
|
372
|
+
const observedOrigins = [
|
|
373
|
+
...new Set(
|
|
374
|
+
matches.flatMap(({ url }) => url.origin === void 0 ? [] : [url.origin])
|
|
375
|
+
)
|
|
376
|
+
];
|
|
377
|
+
const observedOrigin = observedOrigins.length === 1 ? observedOrigins[0] : void 0;
|
|
378
|
+
return Object.freeze({
|
|
379
|
+
...dependency,
|
|
380
|
+
...dependency.url === void 0 || dependency.url.origin !== void 0 || observedOrigin === void 0 ? {} : {
|
|
381
|
+
url: Object.freeze({
|
|
382
|
+
...dependency.url,
|
|
383
|
+
origin: observedOrigin
|
|
384
|
+
})
|
|
385
|
+
},
|
|
386
|
+
execution: "observed",
|
|
387
|
+
observationIds: Object.freeze([
|
|
388
|
+
.../* @__PURE__ */ new Set([...dependency.observationIds, ...matches.map(({ id }) => id)])
|
|
389
|
+
]),
|
|
390
|
+
evidenceIds: Object.freeze([
|
|
391
|
+
.../* @__PURE__ */ new Set([...dependency.evidenceIds, ...matches.map(({ id }) => id)])
|
|
392
|
+
])
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
return Object.freeze({
|
|
396
|
+
dependencies: Object.freeze(merged),
|
|
397
|
+
matchedObservationIds
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
function appendRuntimeEvidence(evidence, observations, matchedIds) {
|
|
401
|
+
const existing = new Set(evidence.map(({ id }) => id));
|
|
402
|
+
return Object.freeze([
|
|
403
|
+
...evidence,
|
|
404
|
+
...observations.flatMap(
|
|
405
|
+
(observation) => matchedIds.has(observation.id) && !existing.has(observation.id) ? [runtimeEvidence(observation)] : []
|
|
406
|
+
)
|
|
407
|
+
]);
|
|
408
|
+
}
|
|
409
|
+
function mergeComponentDataFlowReport(report, observations) {
|
|
410
|
+
const componentObservations = observations.filter(
|
|
411
|
+
(observation) => observation.componentSourceId === void 0 || observation.componentSourceId === report.component.componentSourceId
|
|
412
|
+
);
|
|
413
|
+
const merged = mergeDependencies(report.dependencies, componentObservations);
|
|
414
|
+
return (0, import_shared.limitDataFlowReportCollections)(
|
|
415
|
+
Object.freeze({
|
|
416
|
+
...report,
|
|
417
|
+
dependencies: merged.dependencies,
|
|
418
|
+
evidence: appendRuntimeEvidence(
|
|
419
|
+
report.evidence,
|
|
420
|
+
componentObservations,
|
|
421
|
+
merged.matchedObservationIds
|
|
422
|
+
)
|
|
423
|
+
}),
|
|
424
|
+
{ mode: "observation" }
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
function unassignedDependency(observation) {
|
|
428
|
+
const isRpc = observation.transport === "trpc";
|
|
429
|
+
return Object.freeze({
|
|
430
|
+
id: observation.id,
|
|
431
|
+
kind: isRpc ? "rpc" : "http",
|
|
432
|
+
direction: observation.method === "GET" || observation.method === "HEAD" || observation.method === "QUERY" || observation.method === "SUBSCRIPTION" ? "read" : "write",
|
|
433
|
+
execution: "observed",
|
|
434
|
+
proof: "unavailable",
|
|
435
|
+
association: "unassigned",
|
|
436
|
+
method: observation.method,
|
|
437
|
+
...isRpc ? observation.operation === void 0 ? {} : { operation: observation.operation } : { url: observation.url },
|
|
438
|
+
parameters: Object.freeze(
|
|
439
|
+
(isRpc ? [] : observation.url.queryKeys).map(
|
|
440
|
+
(path) => Object.freeze({
|
|
441
|
+
path,
|
|
442
|
+
position: "query",
|
|
443
|
+
sensitive: (0, import_shared.isSensitiveName)(path),
|
|
444
|
+
valueState: "not-collected",
|
|
445
|
+
evidenceIds: Object.freeze([observation.id])
|
|
446
|
+
})
|
|
447
|
+
)
|
|
448
|
+
),
|
|
449
|
+
response: Object.freeze({
|
|
450
|
+
consumedFields: Object.freeze([])
|
|
451
|
+
}),
|
|
452
|
+
suppliedBindings: Object.freeze([]),
|
|
453
|
+
locationIds: Object.freeze([]),
|
|
454
|
+
evidenceIds: Object.freeze([observation.id]),
|
|
455
|
+
observationIds: Object.freeze([observation.id])
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
function mergePageDataFlowReport(report, observations) {
|
|
459
|
+
const currentObservations = observations.filter(
|
|
460
|
+
({ freshness }) => freshness === "current"
|
|
461
|
+
);
|
|
462
|
+
const merged = mergeDependencies(report.dependencies, currentObservations);
|
|
463
|
+
const unassigned = currentObservations.filter(({ id }) => !merged.matchedObservationIds.has(id)).map(unassignedDependency);
|
|
464
|
+
const allObservationIds = new Set(currentObservations.map(({ id }) => id));
|
|
465
|
+
return (0, import_shared.limitDataFlowReportCollections)(
|
|
466
|
+
Object.freeze({
|
|
467
|
+
...report,
|
|
468
|
+
dependencies: Object.freeze([...merged.dependencies, ...unassigned]),
|
|
469
|
+
evidence: appendRuntimeEvidence(
|
|
470
|
+
report.evidence,
|
|
471
|
+
currentObservations,
|
|
472
|
+
allObservationIds
|
|
473
|
+
)
|
|
474
|
+
}),
|
|
475
|
+
{ mode: "observation" }
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// src/data-flow-panel-entry.ts
|
|
480
|
+
function installDataFlowPanelExtension() {
|
|
481
|
+
registerDataFlowExtension(
|
|
482
|
+
Object.freeze({
|
|
483
|
+
createPanel: createDataFlowPanel,
|
|
484
|
+
getComponentRegistration(component) {
|
|
485
|
+
return getDataFlowRuntime()?.getComponentRegistration(component);
|
|
486
|
+
},
|
|
487
|
+
observations(routeKey) {
|
|
488
|
+
const runtime = getDataFlowRuntime();
|
|
489
|
+
runtime?.updateRoute(routeKey);
|
|
490
|
+
return runtime?.observations() ?? Object.freeze([]);
|
|
491
|
+
},
|
|
492
|
+
mergeComponentReport: mergeComponentDataFlowReport,
|
|
493
|
+
mergePageReport: mergePageDataFlowReport
|
|
494
|
+
})
|
|
495
|
+
);
|
|
496
|
+
}
|
|
327
497
|
// Annotate the CommonJS export names for ESM import in node:
|
|
328
498
|
0 && (module.exports = {
|
|
329
499
|
createDataFlowPanel,
|
|
330
500
|
getDataFlowExtension,
|
|
501
|
+
installDataFlowPanelExtension,
|
|
331
502
|
registerDataFlowExtension
|
|
332
503
|
});
|
|
333
504
|
//# sourceMappingURL=data-flow-panel.cjs.map
|