@thoughtbot/superglue 2.0.0-alpha.7 → 2.0.0-alpha.9

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../lib/action_creators/index.ts","../../lib/utils/url.ts","../../lib/utils/immutability.ts","../../lib/config.ts","../../lib/utils/limited_set.ts","../../lib/utils/request.ts","../../lib/utils/window.ts","../../lib/actions.ts","../../lib/utils/proxy.ts","../../lib/action_creators/requests.ts","../../lib/action_creators/stream.ts"],"sourcesContent":["import { urlToPageKey, getIn, setIn, propsAtParam } from '../utils'\nimport {\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n handleGraft,\n saveFragment,\n handleFragmentGraft,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n SaveAndProcessPageThunk,\n DefermentThunk,\n Defer,\n JSONMappable,\n PageResponse,\n Page,\n} from '../types'\nimport { handleStreamResponse } from './stream'\nimport { createProxy } from '../utils/proxy'\nexport * from './requests'\n\nfunction fetchDeferments(\n pageKey: string,\n defers: Defer[] = []\n): DefermentThunk {\n pageKey = urlToPageKey(pageKey)\n return (dispatch) => {\n const fetches = defers\n .filter(({ type }) => type === 'auto')\n .map(function ({\n url,\n successAction = GRAFTING_SUCCESS,\n failAction = GRAFTING_ERROR,\n }) {\n // props_at will always be present in a graft response\n // That's why this is marked `as string`\n const keyPath = propsAtParam(url) as string\n\n return dispatch(remote(url, { pageKey }))\n .then(() => {\n dispatch({\n type: successAction,\n payload: {\n pageKey,\n keyPath,\n },\n })\n })\n .catch((err) => {\n dispatch({\n type: failAction,\n payload: {\n url,\n err,\n pageKey,\n keyPath,\n },\n })\n })\n })\n\n return Promise.all(fetches)\n }\n}\n\nfunction addPlaceholdersToDeferredNodes(\n existingPage: Page,\n page: PageResponse\n): PageResponse {\n const { defers = [] } = existingPage\n\n const prevDefers = defers.map(({ path }) => {\n const node = getIn(existingPage, path)\n const copy = JSON.stringify(node)\n return [path, JSON.parse(copy)]\n })\n\n return prevDefers.reduce((memo, [path, node]) => {\n return setIn(page, path, node)\n }, page)\n}\n\n/**\n * Save and process a rendered view from PropsTemplate. This is the primitive\n * function that `visit` and `remote` calls when it receives a page.\n *\n * If you render a page outside the normal request response cycle, e.g,\n * websocket, you can use this function to save the payload.\n */\nexport function saveAndProcessPage(\n pageKey: string,\n page: PageResponse\n): SaveAndProcessPageThunk {\n return (dispatch, getState) => {\n pageKey = urlToPageKey(pageKey)\n let nextPage = page\n\n const state = getState()\n if (page.action === 'savePage' && state.pages[pageKey]) {\n const existingPage = createProxy(\n state.pages[pageKey],\n { current: state.fragments },\n new Set(),\n new WeakMap()\n )\n\n nextPage = JSON.parse(\n JSON.stringify(addPlaceholdersToDeferredNodes(existingPage, nextPage))\n ) as PageResponse\n }\n\n page.fragments.reverse().forEach((fragment) => {\n const { id, path } = fragment\n const node = getIn(nextPage, path) as JSONMappable\n nextPage = setIn(nextPage, path, { __id: id })\n\n dispatch(\n saveFragment({\n fragmentId: id,\n data: node,\n })\n )\n })\n\n if (nextPage.action === 'graft') {\n if (typeof nextPage.fragmentContext === 'string') {\n dispatch(\n handleFragmentGraft({\n fragmentId: nextPage.fragmentContext,\n response: nextPage,\n })\n )\n } else {\n dispatch(handleGraft({ pageKey, page: nextPage }))\n }\n } else if (nextPage.action === 'handleStreamResponse') {\n // We resolve the promise here because fragment responses\n // have deferment disabled.\n dispatch(handleStreamResponse(nextPage))\n return Promise.resolve()\n } else {\n dispatch(saveResponse({ pageKey, page: nextPage }))\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, nextPage.defers)).then(() =>\n Promise.resolve()\n )\n } else {\n return Promise.resolve()\n }\n }\n}\n","import { PageKey } from '../types'\n\nconst FAKE_ORIGIN = 'https://example.com'\n\nexport function pathQuery(url: string): string {\n const { pathname, search: query } = new URL(url, FAKE_ORIGIN)\n\n return pathname + query\n}\n\nexport function pathQueryHash(url: string): string {\n const { pathname, hash, search: query } = new URL(url, FAKE_ORIGIN)\n\n return pathname + query + hash\n}\n\nexport function hasPropsAt(url: string): boolean {\n const { searchParams } = new URL(url, FAKE_ORIGIN)\n\n return searchParams.has('props_at')\n}\n\nexport function propsAtParam(url: string): string | null {\n const { searchParams } = new URL(url, FAKE_ORIGIN)\n\n return searchParams.get('props_at')\n}\n\nexport function withFormatJson(url: string): string {\n const parsed = new URL(url, FAKE_ORIGIN)\n parsed.searchParams.set('format', 'json')\n\n return parsed.href.replace(parsed.origin, '')\n}\n\nexport function removePropsAt(url: string): string {\n const parsed = new URL(url, FAKE_ORIGIN)\n parsed.searchParams.delete('props_at')\n\n return parsed.href.replace(parsed.origin, '')\n}\n\n/**\n * Converts a url to a PageKey.\n *\n * @param url\n * @returns\n */\nexport function urlToPageKey(url: string): PageKey {\n const parsed = new URL(url, FAKE_ORIGIN)\n parsed.searchParams.delete('props_at')\n parsed.searchParams.delete('format')\n\n return pathQuery(parsed.toString())\n}\n\nexport function withoutHash(url: string): string {\n const parsed = new URL(url, FAKE_ORIGIN)\n parsed.hash = ''\n\n return parsed.href.replace(parsed.origin, '')\n}\n\nexport function formatForXHR(url: string): string {\n const formats = [withoutHash, withFormatJson]\n\n return formats.reduce((memo, f) => f(memo), url)\n}\n\nexport function parsePageKey(pageKey: PageKey) {\n const { pathname, searchParams } = new URL(pageKey, FAKE_ORIGIN)\n\n const search = Object.fromEntries(searchParams)\n\n return {\n pathname,\n search,\n }\n}\n","// These were taken from Scour.js\n// Then, modified to respect the id=0 keypath\n\nimport { JSONMappable, JSONValue, Keypath } from '../types'\n\nconst canLookAhead = /^[\\da-zA-Z\\-_]+=[\\da-zA-Z\\-_]+$/\n\nclass KeyPathError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'KeyPathError'\n }\n}\n\n/**\n * Retrieves data from a JSON object using a {@link Keypath}\n *\n * @param node\n * @param path\n * @returns\n */\nfunction getIn(node: JSONMappable, path: Keypath): JSONValue {\n const keyPath = normalizeKeyPath(path)\n let result: JSONValue = node\n let i: number\n\n for (i = 0; i < keyPath.length; i++) {\n const key = keyPath[i]\n\n if (typeof result === 'object' && result !== null) {\n if (!Array.isArray(result) && canLookAhead.test(key)) {\n throw new KeyPathError(\n `Expected to find an Array when using the key: ${key}`\n )\n }\n\n result = atKey(result, key)\n } else {\n throw new KeyPathError(\n `Expected to traverse an Array or Obj, got ${JSON.stringify(result)}`\n )\n }\n }\n\n if (i === keyPath.length) {\n return result\n } else {\n return undefined\n }\n}\n\nfunction clone(node: JSONMappable): JSONMappable {\n return Array.isArray(node) ? [].slice.call(node) : { ...node }\n}\n\nfunction getKey(node: JSONMappable, key: string): string | number | never {\n if (Array.isArray(node) && Number.isNaN(Number(key))) {\n const key_parts = Array.from(key.split('='))\n const attr = key_parts[0]\n const id = key_parts[1]\n\n if (!id || !attr) {\n return key\n }\n\n let i: number\n let child: JSONValue\n\n for (i = 0; i < node.length; i++) {\n child = node[i]\n if (\n typeof child === 'object' &&\n !Array.isArray(child) &&\n child !== null\n ) {\n const val = child[attr]\n if (val && val.toString() === id) {\n break\n }\n } else {\n throw new KeyPathError(`Could not look ahead ${key} at ${child}`)\n }\n }\n\n if (i === node.length) {\n throw new KeyPathError(`Could not find ${key} while looking ahead`)\n }\n\n return i\n } else {\n return key\n }\n}\n\nfunction atKey(node: JSONMappable, key: string) {\n const actualKey = getKey(node, key)\n\n if (Array.isArray(node)) {\n return node[actualKey as number]\n } else {\n return node[actualKey]\n }\n}\n\nfunction normalizeKeyPath(path: string): string[] {\n if (typeof path === 'string') {\n path = path.replace(/ /g, '')\n if (path === '') {\n return []\n }\n\n return path.split('.')\n } else {\n return path\n }\n}\n/**\n * Sets data into a JSON object using a {@link Keypath}\n *\n * @param object\n * @param path\n * @param value\n * @returns\n */\nfunction setIn<T extends JSONMappable>(\n object: T,\n path: string,\n value: JSONValue\n): T | never {\n const keypath = normalizeKeyPath(path)\n\n const results: {\n 0: T\n [key: number]: JSONValue\n } = { 0: object }\n\n const parents: {\n 0: T\n [key: number]: JSONValue\n } = { 0: object }\n\n let i: number\n\n for (i = 0; i < keypath.length; i++) {\n const parent = parents[i]\n\n if (!(typeof parent === 'object' && parent !== null)) {\n throw new KeyPathError(\n `Expected to traverse an Array or Obj, got ${JSON.stringify(parent)}`\n )\n }\n\n const child = atKey(parent, keypath[i])\n parents[i + 1] = child\n }\n\n results[keypath.length] = value\n\n for (i = keypath.length - 1; i >= 0; i--) {\n // Parents will always have a JSONValue at\n // keypath.length so this loop skips that one element\n // Every other element in parents is a JSONMappable\n const target = clone(parents[i] as JSONMappable)\n results[i] = target\n const key = getKey(results[i] as JSONMappable, keypath[i])\n if (Array.isArray(target)) {\n target[key as number] = results[i + 1]\n } else {\n target[key] = results[i + 1]\n }\n }\n\n return results[0]\n}\n\nexport { getIn, setIn, KeyPathError }\n","export const config = {\n baseUrl: '',\n maxPages: 20,\n}\n","export class LimitedSet extends Set {\n private maxSize: number\n\n constructor(maxSize: number) {\n super()\n this.maxSize = maxSize\n }\n\n add(value: unknown) {\n if (this.size >= this.maxSize) {\n const iterator = this.values()\n const oldestValue = iterator.next().value\n this.delete(oldestValue)\n }\n super.add(value)\n\n return this\n }\n}\n","import { formatForXHR } from './url'\nimport { config } from '../config'\nimport { BasicRequestInit, ParsedResponse, RootState } from '../types'\nimport { LimitedSet } from './limited_set'\nimport { v4 as uuidv4 } from 'uuid'\n\nexport const lastRequestIds = new LimitedSet(20)\n\nexport function isValidResponse(xhr: Response): boolean {\n return isValidContent(xhr) && !downloadingFile(xhr)\n}\n\nexport function isValidContent(rsp: Response): boolean {\n const contentType = rsp.headers.get('content-type')\n const jsContent = /^(?:application\\/json)(?:;|$)/\n\n return !!(contentType && contentType.match(jsContent))\n}\n\nfunction downloadingFile(xhr: Response): boolean {\n const disposition = xhr.headers.get('content-disposition')\n\n return !!(disposition && disposition.match(/^attachment/) !== null)\n}\n\nclass SuperglueResponseError extends Error {\n response: Response\n\n constructor(message: string) {\n super(message)\n this.name = 'SuperglueResponseError'\n }\n}\n\nexport function validateResponse(args: ParsedResponse): ParsedResponse {\n const { rsp } = args\n if (isValidResponse(rsp)) {\n return args\n } else {\n const error = new SuperglueResponseError('Invalid Superglue Response')\n error.response = rsp\n throw error\n }\n}\n\nexport function handleServerErrors(args: ParsedResponse): ParsedResponse {\n const { rsp } = args\n if (!rsp.ok && rsp.status !== 422) {\n if (rsp.status === 406) {\n console.error(\n \"Superglue encountered a 406 Not Acceptable response. This can happen if you used respond_to and didn't specify format.json in the block. Try adding it to your respond_to. For example:\\n\\n\" +\n 'respond_to do |format|\\n' +\n ' format.html\\n' +\n ' format.json\\n' +\n ' format.csv\\n' +\n 'end'\n )\n }\n const error = new SuperglueResponseError(rsp.statusText)\n error.response = rsp\n throw error\n }\n return args\n}\n\nexport function argsForFetch(\n getState: () => RootState,\n pathQuery: string,\n {\n method = 'GET',\n headers = {},\n body = '',\n signal,\n ...rest\n }: BasicRequestInit = {}\n): [string, BasicRequestInit] {\n method = method.toUpperCase()\n const currentState = getState().superglue\n\n const nextHeaders = { ...headers }\n nextHeaders['x-requested-with'] = 'XMLHttpRequest'\n nextHeaders['accept'] = 'application/json'\n nextHeaders['x-superglue-request'] = 'true'\n\n const requestId = uuidv4()\n lastRequestIds.add(requestId)\n nextHeaders['X-Superglue-Request-Id'] = requestId\n\n if (method != 'GET' && method != 'HEAD') {\n nextHeaders['content-type'] = 'application/json'\n }\n\n if (body instanceof FormData) {\n delete nextHeaders['content-type']\n }\n\n if (currentState.csrfToken) {\n nextHeaders['x-csrf-token'] = currentState.csrfToken\n }\n\n const fetchPath = new URL(formatForXHR(pathQuery), config.baseUrl)\n\n const credentials = 'same-origin'\n\n if (!(method == 'GET' || method == 'HEAD')) {\n nextHeaders['x-http-method-override'] = method\n method = 'POST'\n }\n\n const options: BasicRequestInit = {\n method,\n headers: nextHeaders,\n body,\n credentials,\n signal,\n }\n\n if (currentState.currentPageKey) {\n const referrer = new URL(currentState.currentPageKey, config.baseUrl)\n\n options.referrer = referrer.toString()\n }\n\n if (method == 'GET' || method == 'HEAD') {\n if (options.body instanceof FormData) {\n const allData = new URLSearchParams(\n options.body as unknown as Record<string, string>\n )\n\n // Form data should override anything in the URL params First we\n // delete every key. Then append the new keys accounting for\n // duplicate keys that represent structural arrays.\n allData.forEach((value, key) => fetchPath.searchParams.delete(key))\n allData.forEach((value, key) => fetchPath.searchParams.append(key, value))\n }\n\n delete options.body\n }\n\n return [fetchPath.toString(), { ...options, ...rest }]\n}\n\nexport function extractJSON(rsp: Response): PromiseLike<ParsedResponse> {\n return rsp\n .json()\n .then((json) => {\n return { rsp, json }\n })\n .catch((e) => {\n e.response = rsp\n throw e\n })\n}\n\nexport function parseResponse(prm: Response): PromiseLike<ParsedResponse> {\n return Promise.resolve(prm)\n .then(extractJSON)\n .then(handleServerErrors)\n .then(validateResponse)\n}\n","export function needsRefresh(\n prevAssets: string[],\n newAssets: string[]\n): boolean {\n if (prevAssets && newAssets) {\n const hasNewAssets = !newAssets.every((asset) => prevAssets.includes(asset))\n return hasNewAssets\n } else {\n return false\n }\n}\n","import { createAction } from '@reduxjs/toolkit'\nimport {\n FetchArgs,\n PageKey,\n GraftResponse,\n SaveResponse,\n JSONMappable,\n PageResponse,\n} from './types'\nimport { urlToPageKey } from './utils'\n\nexport const GRAFTING_ERROR = '@@superglue/GRAFTING_ERROR'\nexport const GRAFTING_SUCCESS = '@@superglue/GRAFTING_SUCCESS'\n\nexport const saveResponse = createAction(\n '@@superglue/SAVE_RESPONSE',\n ({ pageKey, page }: { pageKey: string; page: SaveResponse }) => {\n pageKey = urlToPageKey(pageKey)\n\n return {\n payload: {\n pageKey,\n page,\n },\n }\n }\n)\n\nexport const handleGraft = createAction(\n '@@superglue/HANDLE_GRAFT',\n ({ pageKey, page }: { pageKey: string; page: GraftResponse }) => {\n pageKey = urlToPageKey(pageKey)\n\n return {\n payload: {\n page,\n pageKey,\n },\n }\n }\n)\n\nexport const superglueError = createAction<{ message: string }>(\n '@@superglue/ERROR'\n)\n\n/**\n * A redux action you can dispatch to copy a page from one pageKey to another. Its\n * a very useful way to create optimistic updates with a URL change. For example:\n *\n * ```\n * import { copyPage, remote } from '@thoughtbot/superglue'\n *\n * dispatch(copyPage({ from: originalKey, to: targetKey}))\n *\n * ... make edits to target page and finally\n *\n * navigateTo(targetKey)\n * ```\n */\nexport const copyPage = createAction<{ from: PageKey; to: PageKey }>(\n '@@superglue/COPY_PAGE'\n)\n\n/**\n * A redux action you can dispatch to remove a page from your store.\n *\n * ```\n * import { removePage } from '@thoughtbot/superglue'\n *\n * dispatch(removePage({ pageKey: '/delete_me_please\"}))\n * ```\n */\nexport const removePage = createAction<{ pageKey: PageKey }>(\n '@@superglue/REMOVE_PAGE'\n)\n\n/**\n * A redux action called before a `fetch` takes place. It will fire in `remote`\n * and `visit`. You can hook into this event in your redux slices like this:\n *\n * ```\n * import { beforeFetch } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(beforeFetch, (state, action) => {\n * ```\n */\nexport const beforeFetch = createAction<{ fetchArgs: FetchArgs }>(\n '@@superglue/BEFORE_FETCH'\n)\n\n/**\n * A redux action called before a `visit` takes place. You can hook into this event\n * in your redux slices like this:\n *\n * ```\n * import { beforeVisit } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(beforeVisit, (state, action) => {\n * ```\n */\nexport const beforeVisit = createAction<{\n currentPageKey: PageKey\n fetchArgs: FetchArgs\n}>('@@superglue/BEFORE_VISIT')\n\n/**\n * A redux action called before `remote` takes place. You can hook into this event\n * in your redux slices like this:\n *\n * ```\n * import { beforeRemote } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(beforeRemote, (state, action) => {\n * ```\n */\nexport const beforeRemote = createAction<{\n currentPageKey: PageKey\n fetchArgs: FetchArgs\n}>('@@superglue/BEFORE_REMOTE')\n\nexport const setCSRFToken = createAction<{\n csrfToken: string | undefined\n}>('@@superglue/SET_CSRF_TOKEN')\n\nexport const historyChange = createAction<{\n pageKey: PageKey\n}>('@@superglue/HISTORY_CHANGE')\n\nexport const setActivePage = createAction<{\n pageKey: PageKey\n}>('@@superglue/SET_ACTIVE_PAGE')\n\nexport const handleFragmentGraft = createAction(\n '@@superglue/HANDLE_FRAGMENT_GRAFT',\n ({\n fragmentId,\n response,\n }: {\n fragmentId: string\n response: GraftResponse\n }) => {\n return {\n payload: {\n response,\n fragmentId,\n },\n }\n }\n)\n\nexport const saveFragment = createAction(\n '@@superglue/SAVE_FRAGMENT',\n ({ fragmentId, data }: { fragmentId: string; data: JSONMappable }) => {\n return {\n payload: {\n fragmentId,\n data,\n },\n }\n }\n)\n\nexport const receiveResponse = createAction(\n '@@superglue/RECEIVE_RESPONSE',\n ({ pageKey, response }: { pageKey: string; response: PageResponse }) => {\n pageKey = urlToPageKey(pageKey)\n\n return {\n payload: {\n pageKey,\n response,\n },\n }\n }\n)\n\nexport const appendToFragment = createAction(\n '@@superglue/APPEND_TO_FRAGMENT',\n ({ data, fragmentId }: { data: JSONMappable; fragmentId: string }) => {\n return {\n payload: {\n data,\n fragmentId,\n },\n }\n }\n)\n\nexport const prependToFragment = createAction(\n '@@superglue/PREPEND_TO_FRAGMENT',\n ({ data, fragmentId }: { data: JSONMappable; fragmentId: string }) => {\n return {\n payload: {\n data,\n fragmentId: fragmentId,\n },\n }\n }\n)\n","import { JSONMappable, AllFragments, Unproxied } from '../types'\nimport { RefObject } from 'react'\n\ntype AccessKeyType = string | symbol | number\n\n// Symbol for accessing original data from proxy\nconst ORIGINAL_TARGET = Symbol('@@originalTarget')\n\nconst ARRAY_GETTER_METHODS = new Set<AccessKeyType>([\n Symbol.iterator,\n 'at',\n 'concat',\n 'entries',\n 'every',\n 'filter',\n 'find',\n 'findIndex',\n 'flat',\n 'flatMap',\n 'forEach',\n 'includes',\n 'indexOf',\n 'join',\n 'keys',\n 'lastIndexOf',\n 'map',\n 'reduce',\n 'reduceRight',\n 'slice',\n 'some',\n 'toString',\n 'values',\n])\n\nconst ARRAY_SETTER_METHODS = new Set<AccessKeyType>([\n 'copyWithin',\n 'fill',\n 'pop',\n 'push',\n 'reverse',\n 'shift',\n 'sort',\n 'splice',\n 'unshift',\n])\n\nfunction isArraySetter<T>(prop: AccessKeyType): prop is keyof Array<T> {\n return ARRAY_SETTER_METHODS.has(prop)\n}\n\nfunction isArrayGetter<T>(prop: AccessKeyType): prop is keyof Array<T> {\n return ARRAY_GETTER_METHODS.has(prop)\n}\n\nfunction convertToInt(prop: AccessKeyType): number | null {\n if (typeof prop === 'symbol') return null\n const num = Number(prop)\n return Number.isInteger(num) ? num : null\n}\n\nfunction isFragmentReference(value: unknown): value is { __id: string } {\n return (\n !!value &&\n typeof value === 'object' &&\n '__id' in value &&\n typeof value.__id === 'string'\n )\n}\n\nfunction createArrayProxy(\n arrayData: unknown[],\n fragments: RefObject<AllFragments>,\n dependencies: Set<string>,\n proxyCache: WeakMap<object, unknown>\n): unknown[] {\n if (proxyCache && proxyCache.has(arrayData)) {\n return proxyCache.get(arrayData) as unknown[]\n }\n\n const proxy = new Proxy(arrayData, {\n get(target, prop) {\n // Return original target for unproxy functionality\n if (prop === ORIGINAL_TARGET) {\n return target\n }\n\n // Handle array methods\n if (isArrayGetter(prop)) {\n const method = target[prop]\n if (typeof method === 'function') {\n return function (...args: unknown[]) {\n // Apply the method directly to the proxy\n // The proxy's numeric index handler will resolve fragments as needed\n return Reflect.apply(method, proxy, args)\n }\n }\n return method\n }\n\n // Block mutations\n if (isArraySetter(prop)) {\n throw new Error(\n `Cannot mutate proxy array. Use Redux actions to update state.`\n )\n }\n\n // Handle numeric indices\n const index = convertToInt(prop)\n if (index !== null && index >= 0 && index < target.length) {\n const item = target[index]\n\n if (isFragmentReference(item)) {\n // Track dependency and resolve fragment\n dependencies.add(item.__id)\n const fragmentData = fragments.current[item.__id]\n\n if (!fragmentData) {\n throw new Error(`Fragment with id \"${item.__id}\" not found`)\n }\n\n return createProxy(fragmentData, fragments, dependencies, proxyCache)\n }\n\n if (typeof item === 'object' && item !== null) {\n if ('$$typeof' in item) {\n // Handle React elements - pass through without proxying\n return item\n } else {\n return createProxy(\n item as JSONMappable,\n fragments,\n dependencies,\n proxyCache\n )\n }\n }\n\n return item\n }\n\n // Handle other array properties (length, etc.)\n return Reflect.get(target, prop)\n },\n\n has(target, prop) {\n if (prop === ORIGINAL_TARGET) {\n return true\n }\n return Reflect.has(target, prop)\n },\n\n set() {\n throw new Error(\n 'Cannot mutate proxy array. Use Redux actions to update state.'\n )\n },\n\n deleteProperty() {\n throw new Error(\n 'Cannot delete properties on proxy array. Use Redux actions to update state.'\n )\n },\n\n defineProperty() {\n throw new Error(\n 'Cannot define properties on proxy array. Use Redux actions to update state.'\n )\n },\n })\n\n if (proxyCache) {\n proxyCache.set(arrayData, proxy)\n }\n\n return proxy\n}\n\nfunction createObjectProxy(\n objectData: object,\n fragments: RefObject<AllFragments>,\n dependencies: Set<string>,\n proxyCache: WeakMap<object, unknown>\n): unknown {\n if (proxyCache && proxyCache.has(objectData)) {\n return proxyCache.get(objectData)\n }\n\n const proxy = new Proxy(objectData as Record<string | symbol, unknown>, {\n get(target: Record<string | symbol, unknown>, prop: string | symbol) {\n // Return original target for unproxy functionality\n if (prop === ORIGINAL_TARGET) {\n return target\n }\n\n const value = target[prop]\n\n if (isFragmentReference(value)) {\n dependencies.add(value.__id)\n const fragmentData = fragments.current[value.__id]\n\n if (!fragmentData) {\n throw new Error(`Fragment with id \"${value.__id}\" not found`)\n }\n\n return createProxy(fragmentData, fragments, dependencies, proxyCache)\n }\n if (typeof value === 'object' && value !== null) {\n if ('$$typeof' in value) {\n // Handle React elements - pass through without proxying\n return value\n } else if (Array.isArray(value)) {\n return createArrayProxy(value, fragments, dependencies, proxyCache)\n } else {\n return createObjectProxy(value, fragments, dependencies, proxyCache)\n }\n }\n\n // For primitive values and undefined, direct access\n return value\n },\n\n has(target, prop) {\n if (prop === ORIGINAL_TARGET) {\n return true\n }\n return Reflect.has(target, prop)\n },\n\n set() {\n throw new Error(\n 'Cannot mutate proxy object. Use Redux actions to update state.'\n )\n },\n\n deleteProperty() {\n throw new Error(\n 'Cannot delete properties on proxy object. Use Redux actions to update state.'\n )\n },\n\n defineProperty() {\n throw new Error(\n 'Cannot define properties on proxy object. Use Redux actions to update state.'\n )\n },\n })\n\n if (proxyCache) {\n proxyCache.set(objectData, proxy)\n }\n\n return proxy\n}\n\nexport function createProxy<T extends JSONMappable>(\n content: T,\n fragments: RefObject<AllFragments>,\n dependencies: Set<string>,\n proxyCache: WeakMap<object, unknown>\n): T {\n if (!content || typeof content !== 'object') {\n return content\n }\n\n // Don't proxy React elements\n if ('$$typeof' in content) {\n return content\n }\n\n if (Array.isArray(content)) {\n return createArrayProxy(content, fragments, dependencies, proxyCache) as T\n }\n\n return createObjectProxy(content, fragments, dependencies, proxyCache) as T\n}\n\nexport function unproxy<T>(proxy: T): Unproxied<T> {\n if (proxy && typeof proxy === 'object' && ORIGINAL_TARGET in proxy) {\n return proxy[ORIGINAL_TARGET] as Unproxied<T>\n }\n return proxy as Unproxied<T>\n}\n","import {\n argsForFetch,\n parseResponse,\n needsRefresh,\n urlToPageKey,\n hasPropsAt,\n propsAtParam,\n removePropsAt,\n} from '../utils'\nimport {\n beforeFetch,\n beforeVisit,\n beforeRemote,\n copyPage,\n superglueError,\n receiveResponse,\n} from '../actions'\nimport { saveAndProcessPage } from './index'\nimport {\n FetchArgs,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n NavigationAction,\n VisitMeta,\n BeforeSave,\n} from '../types'\nimport { createProxy } from '../utils/proxy'\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(superglueError({ message: err.message }))\n console.error(err)\n throw err\n}\n\nfunction buildMeta(\n pageKey: string,\n page: PageResponse,\n state: SuperglueState,\n rsp: Response,\n fetchArgs: FetchArgs\n): Meta {\n const { assets: prevAssets } = state\n const { assets: nextAssets } = page\n\n const meta: Meta = {\n pageKey,\n page,\n redirected: rsp.redirected,\n rsp,\n fetchArgs,\n needsRefresh: needsRefresh(prevAssets, nextAssets),\n }\n\n if (page.action !== 'handleStreamResponse') {\n meta.componentIdentifier = page.componentIdentifier\n }\n\n return meta\n}\n\nexport class MismatchedComponentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MismatchedComponentError'\n }\n}\n\nconst defaultBeforeSave: BeforeSave = (prevPage, receivedPage) => receivedPage\n\nexport const remote: RemoteCreator = (\n path,\n {\n pageKey: targetPageKey,\n force = false,\n beforeSave = defaultBeforeSave,\n ...rest\n } = {}\n) => {\n targetPageKey = targetPageKey && urlToPageKey(targetPageKey)\n\n return (dispatch, getState) => {\n const fetchArgs = argsForFetch(getState, path, rest)\n const currentPageKey = getState().superglue.currentPageKey\n\n dispatch(beforeRemote({ currentPageKey, fetchArgs }))\n dispatch(beforeFetch({ fetchArgs }))\n\n return fetch(...fetchArgs)\n .then(parseResponse)\n .then(({ rsp, json }) => {\n const { superglue, pages = {}, fragments } = getState()\n\n let pageKey\n if (targetPageKey === undefined) {\n const isGet = fetchArgs[1].method === 'GET'\n pageKey = calculatePageKey(rsp, isGet, currentPageKey)\n } else {\n pageKey = targetPageKey\n }\n\n const meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n if (json.action !== 'handleStreamResponse') {\n const existingId = pages[pageKey]?.componentIdentifier\n const receivedId = json.componentIdentifier\n if (!!existingId && existingId != receivedId && !force) {\n const message = `You cannot replace or update an existing page\nlocated at pages[\"${currentPageKey}\"] that has a componentIdentifier\nof \"${existingId}\" with the contents of a page response that has a\ncomponentIdentifier of \"${receivedId}\".\n\nThis can happen if you're using data-sg-remote or remote but your\nresponse redirected to a page with a different componentIdentifier\nthan the target page. \n\nThis limitation exists because the resulting page shape from grafting\n\"${receivedId}\"'s \"${propsAtParam(path)}\" into \"${existingId}\" may not be\ncompatible with the page component associated with \"${existingId}\".\n\nConsider using data-sg-visit, the visit function, or redirect_back to\nthe same page. Or if you're sure you want to proceed, use force: true.\n `\n throw new MismatchedComponentError(message)\n }\n }\n\n dispatch(receiveResponse({ pageKey, response: json }))\n\n const existingPage = createProxy(\n pages[pageKey],\n { current: fragments },\n new Set(),\n new WeakMap()\n )\n\n const page = JSON.parse(\n JSON.stringify(beforeSave(existingPage, json))\n ) as PageResponse\n\n return dispatch(saveAndProcessPage(pageKey, page)).then(() => meta)\n })\n .catch((e) => handleFetchErr(e, fetchArgs, dispatch))\n }\n}\n\nlet lastVisitController = {\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n abort: (_reason: string) => {\n // noop\n },\n}\n\nexport const visit: VisitCreator = (\n path,\n {\n placeholderKey,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\n revisit = false,\n ...rest\n } = {}\n) => {\n return (dispatch, getState) => {\n const currentPageKey = getState().superglue.currentPageKey\n placeholderKey =\n (placeholderKey && urlToPageKey(placeholderKey)) || currentPageKey\n const hasPlaceholder = placeholderKey in getState().pages\n\n if (hasPropsAt(path) && !hasPlaceholder) {\n console.warn(\n `Could not find placeholder with key ${placeholderKey} in state. The props_at param will be ignored`\n )\n path = removePropsAt(path)\n }\n\n const controller = new AbortController()\n const { signal } = controller\n const fetchArgs = argsForFetch(getState, path, {\n ...rest,\n signal,\n })\n\n dispatch(beforeVisit({ currentPageKey, fetchArgs }))\n dispatch(beforeFetch({ fetchArgs }))\n\n lastVisitController.abort(\n 'Aborting the previous `visit`. There can be one visit at a time. Use `remote` if there is a need for async requests.'\n )\n lastVisitController = controller\n\n return fetch(...fetchArgs)\n .then(parseResponse)\n .then(({ rsp, json }) => {\n const { superglue, pages = {}, fragments } = getState()\n const isGet = fetchArgs[1].method === 'GET'\n const pageKey = calculatePageKey(rsp, isGet, currentPageKey)\n\n const meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n if (json.action !== 'handleStreamResponse') {\n if (placeholderKey && hasPropsAt(path) && hasPlaceholder) {\n const existingId = pages[placeholderKey]?.componentIdentifier\n const receivedId = json.componentIdentifier\n if (!!existingId && existingId != receivedId) {\n const message = `You received a page response with a\ncomponentIdentifier \"${receivedId}\" that is different than the\ncomponentIdentifier \"${existingId}\" located at ${placeholderKey}.\n\nThis can happen if you're using data-sg-visit or visit with a\nprops_at param, but the response redirected to a page with a\ndifferent componentIdentifier than the target page. \n\nThis limitation exists because the resulting page shape from grafting\n\"${receivedId}\"'s \"${propsAtParam(path)}\" into \"${existingId}\" may not be\ncompatible with the page component associated with \"${existingId}\".\n\nCheck that you're rendering a page with a matching\ncomponentIdentifier, or consider using redirect_back_with_props_at\nto the same page.\n `\n throw new MismatchedComponentError(message)\n }\n dispatch(copyPage({ from: placeholderKey, to: pageKey }))\n }\n }\n const visitMeta: VisitMeta = {\n ...meta,\n navigationAction: calculateNavAction(\n meta,\n rsp,\n json,\n isGet,\n pageKey,\n currentPageKey,\n revisit\n ),\n }\n\n dispatch(receiveResponse({ pageKey, response: json }))\n\n const existingPage = createProxy(\n pages[pageKey],\n { current: fragments },\n new Set(),\n new WeakMap()\n )\n\n const page = JSON.parse(\n JSON.stringify(beforeSave(existingPage, json))\n ) as PageResponse\n\n return dispatch(saveAndProcessPage(pageKey, page)).then(() => visitMeta)\n })\n .catch((e) => handleFetchErr(e, fetchArgs, dispatch))\n }\n}\n\nfunction calculateNavAction(\n meta: Meta,\n rsp: Response,\n json: PageResponse,\n isGet: boolean,\n pageKey: string,\n currentPageKey: string,\n revisit: boolean\n) {\n let navigationAction: NavigationAction = 'push'\n\n if (json.action === 'handleStreamResponse') {\n return 'none'\n }\n\n if (!rsp.redirected && !isGet) {\n navigationAction = 'replace'\n }\n const isSamePage = pageKey == currentPageKey\n if (isSamePage) {\n navigationAction = 'none'\n }\n if (revisit && isGet) {\n if (rsp.redirected) {\n navigationAction = 'replace'\n } else {\n navigationAction = 'none'\n }\n }\n\n return navigationAction\n}\n\nfunction calculatePageKey(\n rsp: Response,\n isGet: boolean,\n currentPageKey: string\n) {\n let pageKey = urlToPageKey(rsp.url)\n if (!isGet && !rsp.redirected) {\n pageKey = currentPageKey\n }\n\n const contentLocation = rsp.headers.get('content-location')\n if (contentLocation) {\n pageKey = urlToPageKey(contentLocation)\n }\n return pageKey\n}\n","import { ThunkAction } from 'redux-thunk'\nimport { Action } from '@reduxjs/toolkit'\nimport { setIn, getIn } from '../utils'\nimport { appendToFragment, prependToFragment, saveFragment } from '../actions'\nimport { JSONMappable, RootState, StreamResponse } from '../types'\nimport { StreamMessage } from '../hooks/useStreamSource'\n\nexport type StreamThunk = ThunkAction<void, RootState, undefined, Action>\nexport type StreamHandleThunk = ThunkAction<void, RootState, undefined, Action>\n\nexport interface StreamThunkOptions {\n saveAs?: string\n}\n\n/**\n * Stream thunk equivalent to StreamActions.prepend()\n * Prepends data to specified fragments, optionally saving as a new fragment\n */\nexport const streamPrepend = (\n fragments: string[],\n data: JSONMappable,\n options: StreamThunkOptions = {}\n): StreamThunk => {\n return (dispatch) => {\n if (options.saveAs) {\n const { saveAs } = options\n dispatch(\n saveFragment({\n fragmentId: saveAs,\n data,\n })\n )\n\n fragments.forEach((fragmentId) => {\n dispatch(\n prependToFragment({\n fragmentId,\n data: {\n __id: saveAs,\n },\n })\n )\n })\n } else {\n fragments.forEach((fragmentId) => {\n dispatch(\n prependToFragment({\n fragmentId: fragmentId,\n data: data,\n })\n )\n })\n }\n }\n}\n\n/**\n * Stream thunk equivalent to StreamActions.append()\n * Appends data to specified fragments, optionally saving as a new fragment\n */\nexport const streamAppend = (\n fragments: string[],\n data: JSONMappable,\n options: StreamThunkOptions = {}\n): StreamThunk => {\n return (dispatch) => {\n if (options.saveAs) {\n const { saveAs } = options\n dispatch(\n saveFragment({\n fragmentId: saveAs,\n data,\n })\n )\n\n fragments.forEach((fragmentId) => {\n dispatch(\n appendToFragment({\n fragmentId,\n data: {\n __id: saveAs,\n },\n })\n )\n })\n } else {\n fragments.forEach((fragmentId) => {\n dispatch(\n appendToFragment({\n fragmentId,\n data,\n })\n )\n })\n }\n }\n}\n\n/**\n * Stream thunk equivalent to StreamActions.save()\n * Saves data to a specific fragment\n */\nexport const streamSave = (\n fragment: string,\n data: JSONMappable\n): StreamThunk => {\n return (dispatch) => {\n dispatch(\n saveFragment({\n fragmentId: fragment,\n data,\n })\n )\n }\n}\n\nexport const handleStreamMessage = (rawMessage: string): StreamHandleThunk => {\n return (dispatch) => {\n const message = JSON.parse(rawMessage) as StreamMessage\n\n let nextMessage = message\n\n if (message.handler !== 'refresh') {\n message.fragments.reverse().forEach((fragment) => {\n const { id, path } = fragment\n const node = getIn(nextMessage as JSONMappable, path) as JSONMappable\n nextMessage = setIn(nextMessage, path, { __id: id })\n\n dispatch(\n saveFragment({\n fragmentId: id,\n data: node,\n })\n )\n })\n }\n\n if (nextMessage.action === 'handleStreamMessage') {\n if (nextMessage.handler === 'append') {\n dispatch(\n streamAppend(\n nextMessage.fragmentIds,\n nextMessage.data,\n nextMessage.options\n )\n )\n }\n\n if (nextMessage.handler === 'prepend') {\n dispatch(\n streamPrepend(\n nextMessage.fragmentIds,\n nextMessage.data,\n nextMessage.options\n )\n )\n }\n\n if (nextMessage.handler === 'save') {\n dispatch(streamSave(nextMessage.fragmentIds[0], nextMessage.data))\n }\n }\n }\n}\n\nexport const handleStreamResponse = (\n response: StreamResponse\n): StreamHandleThunk => {\n return (dispatch) => {\n let nextResponse = response\n\n nextResponse.fragments.reverse().forEach((fragment) => {\n const { id, path } = fragment\n const node = getIn(nextResponse as JSONMappable, path) as JSONMappable\n nextResponse = setIn(nextResponse, path, { __id: id })\n\n dispatch(\n saveFragment({\n fragmentId: id,\n data: node,\n })\n )\n })\n\n nextResponse.data.forEach((message) => {\n if (message.handler === 'append') {\n dispatch(\n streamAppend(message.fragmentIds, message.data, message.options)\n )\n }\n\n if (message.handler === 'prepend') {\n dispatch(\n streamPrepend(message.fragmentIds, message.data, message.options)\n )\n }\n\n if (message.handler === 'save') {\n dispatch(streamSave(message.fragmentIds[0], message.data))\n }\n })\n }\n}\n"],"mappings":"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","names":["pathQuery","uuidv4"]}
1
+ {"version":3,"sources":["../../lib/action_creators/index.ts","../../lib/utils/url.ts","../../lib/utils/immutability.ts","../../lib/config.ts","../../lib/utils/limited_set.ts","../../lib/utils/request.ts","../../lib/utils/window.ts","../../lib/actions.ts","../../lib/utils/proxy.ts","../../lib/action_creators/requests.ts","../../lib/action_creators/stream.ts"],"sourcesContent":["import { urlToPageKey, getIn, setIn, propsAtParam } from '../utils'\nimport {\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n handleGraft,\n saveFragment,\n handleFragmentGraft,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n SaveAndProcessPageThunk,\n DefermentThunk,\n Defer,\n JSONMappable,\n PageResponse,\n Page,\n} from '../types'\nimport { handleStreamResponse } from './stream'\nimport { createProxy } from '../utils/proxy'\nexport * from './requests'\n\nfunction fetchDeferments(\n pageKey: string,\n defers: Defer[] = []\n): DefermentThunk {\n pageKey = urlToPageKey(pageKey)\n return (dispatch) => {\n const fetches = defers\n .filter(({ type }) => type === 'auto')\n .map(function ({\n url,\n successAction = GRAFTING_SUCCESS,\n failAction = GRAFTING_ERROR,\n }) {\n // props_at will always be present in a graft response\n // That's why this is marked `as string`\n const keyPath = propsAtParam(url) as string\n\n return dispatch(remote(url, { pageKey }))\n .then(() => {\n dispatch({\n type: successAction,\n payload: {\n pageKey,\n keyPath,\n },\n })\n })\n .catch((err) => {\n dispatch({\n type: failAction,\n payload: {\n url,\n err,\n pageKey,\n keyPath,\n },\n })\n })\n })\n\n return Promise.all(fetches)\n }\n}\n\nfunction addPlaceholdersToDeferredNodes(\n existingPage: Page,\n page: PageResponse\n): PageResponse {\n const { defers = [] } = existingPage\n\n const prevDefers = defers.map(({ path }) => {\n const node = getIn(existingPage, path)\n const copy = JSON.stringify(node)\n return [path, JSON.parse(copy)]\n })\n\n return prevDefers.reduce((memo, [path, node]) => {\n return setIn(page, path, node)\n }, page)\n}\n\n/**\n * Save and process a rendered view from PropsTemplate. This is the primitive\n * function that `visit` and `remote` calls when it receives a page.\n *\n * If you render a page outside the normal request response cycle, e.g,\n * websocket, you can use this function to save the payload.\n */\nexport function saveAndProcessPage(\n pageKey: string,\n page: PageResponse\n): SaveAndProcessPageThunk {\n return (dispatch, getState) => {\n pageKey = urlToPageKey(pageKey)\n let nextPage = page\n\n const state = getState()\n if (page.action === 'savePage' && state.pages[pageKey]) {\n const existingPage = createProxy(\n state.pages[pageKey],\n { current: state.fragments },\n new Set(),\n new WeakMap()\n )\n\n nextPage = JSON.parse(\n JSON.stringify(addPlaceholdersToDeferredNodes(existingPage, nextPage))\n ) as PageResponse\n }\n\n page.fragments\n .slice()\n .reverse()\n .forEach((fragment) => {\n const { id, path } = fragment\n const node = getIn(nextPage, path) as JSONMappable\n nextPage = setIn(nextPage, path, { __id: id })\n\n dispatch(\n saveFragment({\n fragmentId: id,\n data: node,\n })\n )\n })\n\n if (nextPage.action === 'graft') {\n if (typeof nextPage.fragmentContext === 'string') {\n dispatch(\n handleFragmentGraft({\n fragmentId: nextPage.fragmentContext,\n response: nextPage,\n })\n )\n } else {\n dispatch(handleGraft({ pageKey, page: nextPage }))\n }\n } else if (nextPage.action === 'handleStreamResponse') {\n // We resolve the promise here because fragment responses\n // have deferment disabled.\n dispatch(handleStreamResponse(nextPage))\n return Promise.resolve()\n } else {\n dispatch(saveResponse({ pageKey, page: nextPage }))\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, nextPage.defers)).then(() =>\n Promise.resolve()\n )\n } else {\n return Promise.resolve()\n }\n }\n}\n","import { PageKey } from '../types'\n\nconst FAKE_ORIGIN = 'https://example.com'\n\nexport function pathQuery(url: string): string {\n const { pathname, search: query } = new URL(url, FAKE_ORIGIN)\n\n return pathname + query\n}\n\nexport function pathQueryHash(url: string): string {\n const { pathname, hash, search: query } = new URL(url, FAKE_ORIGIN)\n\n return pathname + query + hash\n}\n\nexport function hasPropsAt(url: string): boolean {\n const { searchParams } = new URL(url, FAKE_ORIGIN)\n\n return searchParams.has('props_at')\n}\n\nexport function propsAtParam(url: string): string | null {\n const { searchParams } = new URL(url, FAKE_ORIGIN)\n\n return searchParams.get('props_at')\n}\n\nexport function withFormatJson(url: string): string {\n const parsed = new URL(url, FAKE_ORIGIN)\n parsed.searchParams.set('format', 'json')\n\n return parsed.href.replace(parsed.origin, '')\n}\n\nexport function removePropsAt(url: string): string {\n const parsed = new URL(url, FAKE_ORIGIN)\n parsed.searchParams.delete('props_at')\n\n return parsed.href.replace(parsed.origin, '')\n}\n\n/**\n * Converts a url to a PageKey.\n *\n * @param url\n * @returns\n */\nexport function urlToPageKey(url: string): PageKey {\n const parsed = new URL(url, FAKE_ORIGIN)\n parsed.searchParams.delete('props_at')\n parsed.searchParams.delete('format')\n\n return pathQuery(parsed.toString())\n}\n\nexport function withoutHash(url: string): string {\n const parsed = new URL(url, FAKE_ORIGIN)\n parsed.hash = ''\n\n return parsed.href.replace(parsed.origin, '')\n}\n\nexport function formatForXHR(url: string): string {\n const formats = [withoutHash, withFormatJson]\n\n return formats.reduce((memo, f) => f(memo), url)\n}\n\nexport function parsePageKey(pageKey: PageKey) {\n const { pathname, searchParams } = new URL(pageKey, FAKE_ORIGIN)\n\n const search = Object.fromEntries(searchParams)\n\n return {\n pathname,\n search,\n }\n}\n","// These were taken from Scour.js\n// Then, modified to respect the id=0 keypath\n\nimport { JSONMappable, JSONValue, Keypath } from '../types'\n\nconst canLookAhead = /^[\\da-zA-Z\\-_]+=[\\da-zA-Z\\-_]+$/\n\nclass KeyPathError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'KeyPathError'\n }\n}\n\n/**\n * Retrieves data from a JSON object using a {@link Keypath}\n *\n * @param node\n * @param path\n * @returns\n */\nfunction getIn(node: JSONMappable, path: Keypath): JSONValue {\n const keyPath = normalizeKeyPath(path)\n let result: JSONValue = node\n let i: number\n\n for (i = 0; i < keyPath.length; i++) {\n const key = keyPath[i]\n\n if (typeof result === 'object' && result !== null) {\n if (!Array.isArray(result) && canLookAhead.test(key)) {\n throw new KeyPathError(\n `Expected to find an Array when using the key: ${key}`\n )\n }\n\n result = atKey(result, key)\n } else {\n throw new KeyPathError(\n `Expected to traverse an Array or Obj, got ${JSON.stringify(result)}`\n )\n }\n }\n\n if (i === keyPath.length) {\n return result\n } else {\n return undefined\n }\n}\n\nfunction clone(node: JSONMappable): JSONMappable {\n return Array.isArray(node) ? [].slice.call(node) : { ...node }\n}\n\nfunction getKey(node: JSONMappable, key: string): string | number | never {\n if (Array.isArray(node) && Number.isNaN(Number(key))) {\n const key_parts = Array.from(key.split('='))\n const attr = key_parts[0]\n const id = key_parts[1]\n\n if (!id || !attr) {\n return key\n }\n\n let i: number\n let child: JSONValue\n\n for (i = 0; i < node.length; i++) {\n child = node[i]\n if (\n typeof child === 'object' &&\n !Array.isArray(child) &&\n child !== null\n ) {\n const val = child[attr]\n if (val && val.toString() === id) {\n break\n }\n } else {\n throw new KeyPathError(`Could not look ahead ${key} at ${child}`)\n }\n }\n\n if (i === node.length) {\n throw new KeyPathError(`Could not find ${key} while looking ahead`)\n }\n\n return i\n } else {\n return key\n }\n}\n\nfunction atKey(node: JSONMappable, key: string) {\n const actualKey = getKey(node, key)\n\n if (Array.isArray(node)) {\n return node[actualKey as number]\n } else {\n return node[actualKey]\n }\n}\n\nfunction normalizeKeyPath(path: string): string[] {\n if (typeof path === 'string') {\n path = path.replace(/ /g, '')\n if (path === '') {\n return []\n }\n\n return path.split('.')\n } else {\n return path\n }\n}\n/**\n * Sets data into a JSON object using a {@link Keypath}\n *\n * @param object\n * @param path\n * @param value\n * @returns\n */\nfunction setIn<T extends JSONMappable>(\n object: T,\n path: string,\n value: JSONValue\n): T | never {\n const keypath = normalizeKeyPath(path)\n\n const results: {\n 0: T\n [key: number]: JSONValue\n } = { 0: object }\n\n const parents: {\n 0: T\n [key: number]: JSONValue\n } = { 0: object }\n\n let i: number\n\n for (i = 0; i < keypath.length; i++) {\n const parent = parents[i]\n\n if (!(typeof parent === 'object' && parent !== null)) {\n throw new KeyPathError(\n `Expected to traverse an Array or Obj, got ${JSON.stringify(parent)}`\n )\n }\n\n const child = atKey(parent, keypath[i])\n parents[i + 1] = child\n }\n\n results[keypath.length] = value\n\n for (i = keypath.length - 1; i >= 0; i--) {\n // Parents will always have a JSONValue at\n // keypath.length so this loop skips that one element\n // Every other element in parents is a JSONMappable\n const target = clone(parents[i] as JSONMappable)\n results[i] = target\n const key = getKey(results[i] as JSONMappable, keypath[i])\n if (Array.isArray(target)) {\n target[key as number] = results[i + 1]\n } else {\n target[key] = results[i + 1]\n }\n }\n\n return results[0]\n}\n\nexport { getIn, setIn, KeyPathError }\n","export const config = {\n baseUrl: '',\n maxPages: 20,\n}\n","export class LimitedSet extends Set {\n private maxSize: number\n\n constructor(maxSize: number) {\n super()\n this.maxSize = maxSize\n }\n\n add(value: unknown) {\n if (this.size >= this.maxSize) {\n const iterator = this.values()\n const oldestValue = iterator.next().value\n this.delete(oldestValue)\n }\n super.add(value)\n\n return this\n }\n}\n","import { formatForXHR } from './url'\nimport { config } from '../config'\nimport { BasicRequestInit, ParsedResponse, RootState } from '../types'\nimport { LimitedSet } from './limited_set'\nimport { v4 as uuidv4 } from 'uuid'\n\nexport const lastRequestIds = new LimitedSet(20)\n\nexport function isValidResponse(xhr: Response): boolean {\n return isValidContent(xhr) && !downloadingFile(xhr)\n}\n\nexport function isValidContent(rsp: Response): boolean {\n const contentType = rsp.headers.get('content-type')\n const jsContent = /^(?:application\\/json)(?:;|$)/\n\n return !!(contentType && contentType.match(jsContent))\n}\n\nfunction downloadingFile(xhr: Response): boolean {\n const disposition = xhr.headers.get('content-disposition')\n\n return !!(disposition && disposition.match(/^attachment/) !== null)\n}\n\nclass SuperglueResponseError extends Error {\n response: Response\n\n constructor(message: string) {\n super(message)\n this.name = 'SuperglueResponseError'\n }\n}\n\nexport function validateResponse(args: ParsedResponse): ParsedResponse {\n const { rsp } = args\n if (isValidResponse(rsp)) {\n return args\n } else {\n const error = new SuperglueResponseError('Invalid Superglue Response')\n error.response = rsp\n throw error\n }\n}\n\nexport function handleServerErrors(args: ParsedResponse): ParsedResponse {\n const { rsp } = args\n if (!rsp.ok && rsp.status !== 422) {\n if (rsp.status === 406) {\n console.error(\n \"Superglue encountered a 406 Not Acceptable response. This can happen if you used respond_to and didn't specify format.json in the block. Try adding it to your respond_to. For example:\\n\\n\" +\n 'respond_to do |format|\\n' +\n ' format.html\\n' +\n ' format.json\\n' +\n ' format.csv\\n' +\n 'end'\n )\n }\n const error = new SuperglueResponseError(rsp.statusText)\n error.response = rsp\n throw error\n }\n return args\n}\n\nexport function argsForFetch(\n getState: () => RootState,\n pathQuery: string,\n {\n method = 'GET',\n headers = {},\n body = '',\n signal,\n ...rest\n }: BasicRequestInit = {}\n): [string, BasicRequestInit] {\n method = method.toUpperCase()\n const currentState = getState().superglue\n\n const nextHeaders = { ...headers }\n nextHeaders['x-requested-with'] = 'XMLHttpRequest'\n nextHeaders['accept'] = 'application/json'\n nextHeaders['x-superglue-request'] = 'true'\n\n const requestId = uuidv4()\n lastRequestIds.add(requestId)\n nextHeaders['X-Superglue-Request-Id'] = requestId\n\n if (method != 'GET' && method != 'HEAD') {\n nextHeaders['content-type'] = 'application/json'\n }\n\n if (body instanceof FormData) {\n delete nextHeaders['content-type']\n }\n\n if (currentState.csrfToken) {\n nextHeaders['x-csrf-token'] = currentState.csrfToken\n }\n\n const fetchPath = new URL(formatForXHR(pathQuery), config.baseUrl)\n\n const credentials = 'same-origin'\n\n if (!(method == 'GET' || method == 'HEAD')) {\n nextHeaders['x-http-method-override'] = method\n method = 'POST'\n }\n\n const options: BasicRequestInit = {\n method,\n headers: nextHeaders,\n body,\n credentials,\n signal,\n }\n\n if (currentState.currentPageKey) {\n const referrer = new URL(currentState.currentPageKey, config.baseUrl)\n\n options.referrer = referrer.toString()\n }\n\n if (method == 'GET' || method == 'HEAD') {\n if (options.body instanceof FormData) {\n const allData = new URLSearchParams(\n options.body as unknown as Record<string, string>\n )\n\n // Form data should override anything in the URL params First we\n // delete every key. Then append the new keys accounting for\n // duplicate keys that represent structural arrays.\n allData.forEach((value, key) => fetchPath.searchParams.delete(key))\n allData.forEach((value, key) => fetchPath.searchParams.append(key, value))\n }\n\n delete options.body\n }\n\n return [fetchPath.toString(), { ...options, ...rest }]\n}\n\nexport function extractJSON(rsp: Response): PromiseLike<ParsedResponse> {\n return rsp\n .json()\n .then((json) => {\n return { rsp, json }\n })\n .catch((e) => {\n e.response = rsp\n throw e\n })\n}\n\nexport function parseResponse(prm: Response): PromiseLike<ParsedResponse> {\n return Promise.resolve(prm)\n .then(extractJSON)\n .then(handleServerErrors)\n .then(validateResponse)\n}\n","export function needsRefresh(\n prevAssets: string[],\n newAssets: string[]\n): boolean {\n if (prevAssets && newAssets) {\n const hasNewAssets = !newAssets.every((asset) => prevAssets.includes(asset))\n return hasNewAssets\n } else {\n return false\n }\n}\n","import { createAction } from '@reduxjs/toolkit'\nimport {\n FetchArgs,\n PageKey,\n GraftResponse,\n SaveResponse,\n JSONMappable,\n PageResponse,\n} from './types'\nimport { urlToPageKey } from './utils'\n\nexport const GRAFTING_ERROR = '@@superglue/GRAFTING_ERROR'\nexport const GRAFTING_SUCCESS = '@@superglue/GRAFTING_SUCCESS'\n\nexport const saveResponse = createAction(\n '@@superglue/SAVE_RESPONSE',\n ({ pageKey, page }: { pageKey: string; page: SaveResponse }) => {\n pageKey = urlToPageKey(pageKey)\n\n return {\n payload: {\n pageKey,\n page,\n },\n }\n }\n)\n\nexport const handleGraft = createAction(\n '@@superglue/HANDLE_GRAFT',\n ({ pageKey, page }: { pageKey: string; page: GraftResponse }) => {\n pageKey = urlToPageKey(pageKey)\n\n return {\n payload: {\n page,\n pageKey,\n },\n }\n }\n)\n\nexport const superglueError = createAction<{ message: string }>(\n '@@superglue/ERROR'\n)\n\n/**\n * A redux action you can dispatch to copy a page from one pageKey to another. Its\n * a very useful way to create optimistic updates with a URL change. For example:\n *\n * ```\n * import { copyPage, remote } from '@thoughtbot/superglue'\n *\n * dispatch(copyPage({ from: originalKey, to: targetKey}))\n *\n * ... make edits to target page and finally\n *\n * navigateTo(targetKey)\n * ```\n */\nexport const copyPage = createAction<{ from: PageKey; to: PageKey }>(\n '@@superglue/COPY_PAGE'\n)\n\n/**\n * A redux action you can dispatch to remove a page from your store.\n *\n * ```\n * import { removePage } from '@thoughtbot/superglue'\n *\n * dispatch(removePage({ pageKey: '/delete_me_please\"}))\n * ```\n */\nexport const removePage = createAction<{ pageKey: PageKey }>(\n '@@superglue/REMOVE_PAGE'\n)\n\n/**\n * A redux action called before a `fetch` takes place. It will fire in `remote`\n * and `visit`. You can hook into this event in your redux slices like this:\n *\n * ```\n * import { beforeFetch } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(beforeFetch, (state, action) => {\n * ```\n */\nexport const beforeFetch = createAction<{ fetchArgs: FetchArgs }>(\n '@@superglue/BEFORE_FETCH'\n)\n\n/**\n * A redux action called before a `visit` takes place. You can hook into this event\n * in your redux slices like this:\n *\n * ```\n * import { beforeVisit } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(beforeVisit, (state, action) => {\n * ```\n */\nexport const beforeVisit = createAction<{\n currentPageKey: PageKey\n fetchArgs: FetchArgs\n}>('@@superglue/BEFORE_VISIT')\n\n/**\n * A redux action called before `remote` takes place. You can hook into this event\n * in your redux slices like this:\n *\n * ```\n * import { beforeRemote } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(beforeRemote, (state, action) => {\n * ```\n */\nexport const beforeRemote = createAction<{\n currentPageKey: PageKey\n fetchArgs: FetchArgs\n}>('@@superglue/BEFORE_REMOTE')\n\nexport const setCSRFToken = createAction<{\n csrfToken: string | undefined\n}>('@@superglue/SET_CSRF_TOKEN')\n\nexport const historyChange = createAction<{\n pageKey: PageKey\n}>('@@superglue/HISTORY_CHANGE')\n\nexport const setActivePage = createAction<{\n pageKey: PageKey\n}>('@@superglue/SET_ACTIVE_PAGE')\n\nexport const handleFragmentGraft = createAction(\n '@@superglue/HANDLE_FRAGMENT_GRAFT',\n ({\n fragmentId,\n response,\n }: {\n fragmentId: string\n response: GraftResponse\n }) => {\n return {\n payload: {\n response,\n fragmentId,\n },\n }\n }\n)\n\nexport const saveFragment = createAction(\n '@@superglue/SAVE_FRAGMENT',\n ({ fragmentId, data }: { fragmentId: string; data: JSONMappable }) => {\n return {\n payload: {\n fragmentId,\n data,\n },\n }\n }\n)\n\nexport const receiveResponse = createAction(\n '@@superglue/RECEIVE_RESPONSE',\n ({ pageKey, response }: { pageKey: string; response: PageResponse }) => {\n pageKey = urlToPageKey(pageKey)\n\n return {\n payload: {\n pageKey,\n response,\n },\n }\n }\n)\n\nexport const appendToFragment = createAction(\n '@@superglue/APPEND_TO_FRAGMENT',\n ({ data, fragmentId }: { data: JSONMappable; fragmentId: string }) => {\n return {\n payload: {\n data,\n fragmentId,\n },\n }\n }\n)\n\nexport const prependToFragment = createAction(\n '@@superglue/PREPEND_TO_FRAGMENT',\n ({ data, fragmentId }: { data: JSONMappable; fragmentId: string }) => {\n return {\n payload: {\n data,\n fragmentId: fragmentId,\n },\n }\n }\n)\n","import { JSONMappable, AllFragments, Unproxy } from '../types'\nimport { RefObject } from 'react'\n\ntype AccessKeyType = string | symbol | number\n\n// Symbol for accessing original data from proxy\nconst ORIGINAL_TARGET = Symbol('@@originalTarget')\n\nconst ARRAY_GETTER_METHODS = new Set<AccessKeyType>([\n Symbol.iterator,\n 'at',\n 'concat',\n 'entries',\n 'every',\n 'filter',\n 'find',\n 'findIndex',\n 'flat',\n 'flatMap',\n 'forEach',\n 'includes',\n 'indexOf',\n 'join',\n 'keys',\n 'lastIndexOf',\n 'map',\n 'reduce',\n 'reduceRight',\n 'slice',\n 'some',\n 'toString',\n 'values',\n])\n\nconst ARRAY_SETTER_METHODS = new Set<AccessKeyType>([\n 'copyWithin',\n 'fill',\n 'pop',\n 'push',\n 'reverse',\n 'shift',\n 'sort',\n 'splice',\n 'unshift',\n])\n\nfunction isArraySetter<T>(prop: AccessKeyType): prop is keyof Array<T> {\n return ARRAY_SETTER_METHODS.has(prop)\n}\n\nfunction isArrayGetter<T>(prop: AccessKeyType): prop is keyof Array<T> {\n return ARRAY_GETTER_METHODS.has(prop)\n}\n\nfunction convertToInt(prop: AccessKeyType): number | null {\n if (typeof prop === 'symbol') return null\n const num = Number(prop)\n return Number.isInteger(num) ? num : null\n}\n\nfunction isFragmentReference(value: unknown): value is { __id: string } {\n return (\n !!value &&\n typeof value === 'object' &&\n '__id' in value &&\n typeof value.__id === 'string'\n )\n}\n\nfunction createArrayProxy(\n arrayData: unknown[],\n fragments: RefObject<AllFragments>,\n dependencies: Set<string>,\n proxyCache: WeakMap<object, unknown>\n): unknown[] {\n if (proxyCache && proxyCache.has(arrayData)) {\n return proxyCache.get(arrayData) as unknown[]\n }\n\n const proxy = new Proxy(arrayData, {\n get(target, prop) {\n // Return original target for unproxy functionality\n if (prop === ORIGINAL_TARGET) {\n return target\n }\n\n // Handle array methods\n if (isArrayGetter(prop)) {\n const method = target[prop]\n if (typeof method === 'function') {\n return function (...args: unknown[]) {\n // Apply the method directly to the proxy\n // The proxy's numeric index handler will resolve fragments as needed\n return Reflect.apply(method, proxy, args)\n }\n }\n return method\n }\n\n // Block mutations\n if (isArraySetter(prop)) {\n throw new Error(\n `Cannot mutate proxy array. Use useSetFragment to update state.`\n )\n }\n\n // Handle numeric indices\n const index = convertToInt(prop)\n if (index !== null && index >= 0 && index < target.length) {\n const item = target[index]\n\n if (isFragmentReference(item)) {\n // Track dependency and resolve fragment\n dependencies.add(item.__id)\n const fragmentData = fragments.current[item.__id]\n\n if (!fragmentData) {\n return undefined\n }\n\n return createProxy(fragmentData, fragments, dependencies, proxyCache)\n }\n\n if (typeof item === 'object' && item !== null) {\n if ('$$typeof' in item) {\n // Handle React elements - pass through without proxying\n return item\n } else {\n return createProxy(\n item as JSONMappable,\n fragments,\n dependencies,\n proxyCache\n )\n }\n }\n\n return item\n }\n\n // Handle other array properties (length, etc.)\n return Reflect.get(target, prop)\n },\n\n has(target, prop) {\n if (prop === ORIGINAL_TARGET) {\n return true\n }\n return Reflect.has(target, prop)\n },\n\n set() {\n throw new Error(\n 'Cannot mutate proxy array. Use useSetFragment to update state.'\n )\n },\n\n deleteProperty() {\n throw new Error(\n 'Cannot delete properties on proxy array. Use useSetFragment to update state.'\n )\n },\n\n defineProperty() {\n throw new Error(\n 'Cannot define properties on proxy array. Use useSetFragment to update state.'\n )\n },\n })\n\n if (proxyCache) {\n proxyCache.set(arrayData, proxy)\n }\n\n return proxy\n}\n\nfunction createObjectProxy(\n objectData: object,\n fragments: RefObject<AllFragments>,\n dependencies: Set<string>,\n proxyCache: WeakMap<object, unknown>\n): unknown {\n if (proxyCache && proxyCache.has(objectData)) {\n return proxyCache.get(objectData)\n }\n\n const proxy = new Proxy(objectData as Record<string | symbol, unknown>, {\n get(target: Record<string | symbol, unknown>, prop: string | symbol) {\n // Return original target for unproxy functionality\n if (prop === ORIGINAL_TARGET) {\n return target\n }\n\n const value = target[prop]\n\n if (isFragmentReference(value)) {\n dependencies.add(value.__id)\n const fragmentData = fragments.current[value.__id]\n\n if (!fragmentData) {\n return undefined\n }\n\n return createProxy(fragmentData, fragments, dependencies, proxyCache)\n }\n if (typeof value === 'object' && value !== null) {\n if ('$$typeof' in value) {\n // Handle React elements - pass through without proxying\n return value\n } else if (Array.isArray(value)) {\n return createArrayProxy(value, fragments, dependencies, proxyCache)\n } else {\n return createObjectProxy(value, fragments, dependencies, proxyCache)\n }\n }\n\n // For primitive values and undefined, direct access\n return value\n },\n\n has(target, prop) {\n if (prop === ORIGINAL_TARGET) {\n return true\n }\n return Reflect.has(target, prop)\n },\n\n set() {\n throw new Error(\n 'Cannot mutate proxy object. Use useSetFragment to update state.'\n )\n },\n\n deleteProperty() {\n throw new Error(\n 'Cannot delete properties on proxy object. Use useSetFragment to update state.'\n )\n },\n\n defineProperty() {\n throw new Error(\n 'Cannot define properties on proxy object. Use useSetFragment to update state.'\n )\n },\n })\n\n if (proxyCache) {\n proxyCache.set(objectData, proxy)\n }\n\n return proxy\n}\n\nexport function createProxy<T extends JSONMappable>(\n content: T,\n fragments: RefObject<AllFragments>,\n dependencies: Set<string>,\n proxyCache: WeakMap<object, unknown>\n): T {\n if (!content || typeof content !== 'object') {\n return content\n }\n\n // Don't proxy React elements\n if ('$$typeof' in content) {\n return content\n }\n\n if (Array.isArray(content)) {\n return createArrayProxy(content, fragments, dependencies, proxyCache) as T\n }\n\n return createObjectProxy(content, fragments, dependencies, proxyCache) as T\n}\n\nexport function unproxy<T>(proxy: T): Unproxy<T> {\n if (proxy && typeof proxy === 'object' && ORIGINAL_TARGET in proxy) {\n return proxy[ORIGINAL_TARGET] as Unproxy<T>\n }\n return proxy as Unproxy<T>\n}\n","import {\n argsForFetch,\n parseResponse,\n needsRefresh,\n urlToPageKey,\n hasPropsAt,\n propsAtParam,\n removePropsAt,\n} from '../utils'\nimport {\n beforeFetch,\n beforeVisit,\n beforeRemote,\n copyPage,\n superglueError,\n receiveResponse,\n} from '../actions'\nimport { saveAndProcessPage } from './index'\nimport {\n FetchArgs,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n NavigationAction,\n VisitMeta,\n BeforeSave,\n} from '../types'\nimport { createProxy } from '../utils/proxy'\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(superglueError({ message: err.message }))\n console.error(err)\n throw err\n}\n\nfunction buildMeta(\n pageKey: string,\n page: PageResponse,\n state: SuperglueState,\n rsp: Response,\n fetchArgs: FetchArgs\n): Meta {\n const { assets: prevAssets } = state\n const { assets: nextAssets } = page\n\n const meta: Meta = {\n pageKey,\n page,\n redirected: rsp.redirected,\n rsp,\n fetchArgs,\n needsRefresh: needsRefresh(prevAssets, nextAssets),\n }\n\n if (page.action !== 'handleStreamResponse') {\n meta.componentIdentifier = page.componentIdentifier\n }\n\n return meta\n}\n\nexport class MismatchedComponentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MismatchedComponentError'\n }\n}\n\nconst defaultBeforeSave: BeforeSave = (prevPage, receivedPage) => receivedPage\n\nexport const remote: RemoteCreator = (\n path,\n {\n pageKey: targetPageKey,\n force = false,\n beforeSave = defaultBeforeSave,\n ...rest\n } = {}\n) => {\n targetPageKey = targetPageKey && urlToPageKey(targetPageKey)\n\n return (dispatch, getState) => {\n const fetchArgs = argsForFetch(getState, path, rest)\n const currentPageKey = getState().superglue.currentPageKey\n\n dispatch(beforeRemote({ currentPageKey, fetchArgs }))\n dispatch(beforeFetch({ fetchArgs }))\n\n return fetch(...fetchArgs)\n .then(parseResponse)\n .then(({ rsp, json }) => {\n const { superglue, pages = {}, fragments } = getState()\n\n let pageKey\n if (targetPageKey === undefined) {\n const isGet = fetchArgs[1].method === 'GET'\n pageKey = calculatePageKey(rsp, isGet, currentPageKey)\n } else {\n pageKey = targetPageKey\n }\n\n const meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n if (json.action !== 'handleStreamResponse') {\n const existingId = pages[pageKey]?.componentIdentifier\n const receivedId = json.componentIdentifier\n if (!!existingId && existingId != receivedId && !force) {\n const message = `You cannot replace or update an existing page\nlocated at pages[\"${currentPageKey}\"] that has a componentIdentifier\nof \"${existingId}\" with the contents of a page response that has a\ncomponentIdentifier of \"${receivedId}\".\n\nThis can happen if you're using data-sg-remote or remote but your\nresponse redirected to a page with a different componentIdentifier\nthan the target page. \n\nThis limitation exists because the resulting page shape from grafting\n\"${receivedId}\"'s \"${propsAtParam(path)}\" into \"${existingId}\" may not be\ncompatible with the page component associated with \"${existingId}\".\n\nConsider using data-sg-visit, the visit function, or redirect_back to\nthe same page. Or if you're sure you want to proceed, use force: true.\n `\n throw new MismatchedComponentError(message)\n }\n }\n\n dispatch(\n receiveResponse({\n pageKey,\n response: JSON.parse(JSON.stringify(json)),\n })\n )\n\n const existingPage = createProxy(\n pages[pageKey],\n { current: fragments },\n new Set(),\n new WeakMap()\n )\n\n let page = json\n\n if (json.action === 'savePage' || json.action === 'graft') {\n page = JSON.parse(\n JSON.stringify(beforeSave(existingPage, json))\n ) as PageResponse\n }\n\n return dispatch(saveAndProcessPage(pageKey, page)).then(() => meta)\n })\n .catch((e) => handleFetchErr(e, fetchArgs, dispatch))\n }\n}\n\nlet lastVisitController = {\n /* eslint-disable-next-line @typescript-eslint/no-unused-vars */\n abort: (_reason: string) => {\n // noop\n },\n}\n\nexport const visit: VisitCreator = (\n path,\n {\n placeholderKey,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\n revisit = false,\n ...rest\n } = {}\n) => {\n return (dispatch, getState) => {\n const currentPageKey = getState().superglue.currentPageKey\n placeholderKey =\n (placeholderKey && urlToPageKey(placeholderKey)) || currentPageKey\n const hasPlaceholder = placeholderKey in getState().pages\n\n if (hasPropsAt(path) && !hasPlaceholder) {\n console.warn(\n `Could not find placeholder with key ${placeholderKey} in state. The props_at param will be ignored`\n )\n path = removePropsAt(path)\n }\n\n const controller = new AbortController()\n const { signal } = controller\n const fetchArgs = argsForFetch(getState, path, {\n ...rest,\n signal,\n })\n\n dispatch(beforeVisit({ currentPageKey, fetchArgs }))\n dispatch(beforeFetch({ fetchArgs }))\n\n lastVisitController.abort(\n 'Aborting the previous `visit`. There can be one visit at a time. Use `remote` if there is a need for async requests.'\n )\n lastVisitController = controller\n\n return fetch(...fetchArgs)\n .then(parseResponse)\n .then(({ rsp, json }) => {\n const { superglue, pages = {}, fragments } = getState()\n const isGet = fetchArgs[1].method === 'GET'\n const pageKey = calculatePageKey(rsp, isGet, currentPageKey)\n\n const meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n if (json.action !== 'handleStreamResponse') {\n if (placeholderKey && hasPropsAt(path) && hasPlaceholder) {\n const existingId = pages[placeholderKey]?.componentIdentifier\n const receivedId = json.componentIdentifier\n if (!!existingId && existingId != receivedId) {\n const message = `You received a page response with a\ncomponentIdentifier \"${receivedId}\" that is different than the\ncomponentIdentifier \"${existingId}\" located at ${placeholderKey}.\n\nThis can happen if you're using data-sg-visit or visit with a\nprops_at param, but the response redirected to a page with a\ndifferent componentIdentifier than the target page. \n\nThis limitation exists because the resulting page shape from grafting\n\"${receivedId}\"'s \"${propsAtParam(path)}\" into \"${existingId}\" may not be\ncompatible with the page component associated with \"${existingId}\".\n\nCheck that you're rendering a page with a matching\ncomponentIdentifier, or consider using redirect_back_with_props_at\nto the same page.\n `\n throw new MismatchedComponentError(message)\n }\n dispatch(copyPage({ from: placeholderKey, to: pageKey }))\n }\n }\n const visitMeta: VisitMeta = {\n ...meta,\n navigationAction: calculateNavAction(\n meta,\n rsp,\n json,\n isGet,\n pageKey,\n currentPageKey,\n revisit\n ),\n }\n\n dispatch(\n receiveResponse({\n pageKey,\n response: JSON.parse(JSON.stringify(json)),\n })\n )\n\n const existingPage = createProxy(\n pages[pageKey],\n { current: fragments },\n new Set(),\n new WeakMap()\n )\n\n let page = json\n\n if (json.action === 'savePage' || json.action === 'graft') {\n page = JSON.parse(\n JSON.stringify(beforeSave(existingPage, json))\n ) as PageResponse\n }\n\n return dispatch(saveAndProcessPage(pageKey, page)).then(() => visitMeta)\n })\n .catch((e) => handleFetchErr(e, fetchArgs, dispatch))\n }\n}\n\nfunction calculateNavAction(\n meta: Meta,\n rsp: Response,\n json: PageResponse,\n isGet: boolean,\n pageKey: string,\n currentPageKey: string,\n revisit: boolean\n) {\n let navigationAction: NavigationAction = 'push'\n\n if (json.action === 'handleStreamResponse') {\n return 'none'\n }\n\n if (!rsp.redirected && !isGet) {\n navigationAction = 'replace'\n }\n const isSamePage = pageKey == currentPageKey\n if (isSamePage) {\n navigationAction = 'none'\n }\n if (revisit && isGet) {\n if (rsp.redirected) {\n navigationAction = 'replace'\n } else {\n navigationAction = 'none'\n }\n }\n\n return navigationAction\n}\n\nfunction calculatePageKey(\n rsp: Response,\n isGet: boolean,\n currentPageKey: string\n) {\n let pageKey = urlToPageKey(rsp.url)\n if (!isGet && !rsp.redirected) {\n pageKey = currentPageKey\n }\n\n const contentLocation = rsp.headers.get('content-location')\n if (contentLocation) {\n pageKey = urlToPageKey(contentLocation)\n }\n return pageKey\n}\n","import { ThunkAction } from 'redux-thunk'\nimport { Action } from '@reduxjs/toolkit'\nimport { setIn, getIn } from '../utils'\nimport { appendToFragment, prependToFragment, saveFragment } from '../actions'\nimport { JSONMappable, RootState, StreamResponse } from '../types'\nimport { StreamMessage } from '../hooks/useStreamSource'\n\nexport type StreamThunk = ThunkAction<void, RootState, undefined, Action>\nexport type StreamHandleThunk = ThunkAction<void, RootState, undefined, Action>\n\nexport interface StreamThunkOptions {\n saveAs?: string\n}\n\n/**\n * Stream thunk equivalent to StreamActions.prepend()\n * Prepends data to specified fragments, optionally saving as a new fragment\n */\nexport const streamPrepend = (\n fragments: string[],\n data: JSONMappable,\n options: StreamThunkOptions = {}\n): StreamThunk => {\n return (dispatch) => {\n if (options.saveAs) {\n const { saveAs } = options\n dispatch(\n saveFragment({\n fragmentId: saveAs,\n data,\n })\n )\n\n fragments.forEach((fragmentId) => {\n dispatch(\n prependToFragment({\n fragmentId,\n data: {\n __id: saveAs,\n },\n })\n )\n })\n } else {\n fragments.forEach((fragmentId) => {\n dispatch(\n prependToFragment({\n fragmentId: fragmentId,\n data: data,\n })\n )\n })\n }\n }\n}\n\n/**\n * Stream thunk equivalent to StreamActions.append()\n * Appends data to specified fragments, optionally saving as a new fragment\n */\nexport const streamAppend = (\n fragments: string[],\n data: JSONMappable,\n options: StreamThunkOptions = {}\n): StreamThunk => {\n return (dispatch) => {\n if (options.saveAs) {\n const { saveAs } = options\n dispatch(\n saveFragment({\n fragmentId: saveAs,\n data,\n })\n )\n\n fragments.forEach((fragmentId) => {\n dispatch(\n appendToFragment({\n fragmentId,\n data: {\n __id: saveAs,\n },\n })\n )\n })\n } else {\n fragments.forEach((fragmentId) => {\n dispatch(\n appendToFragment({\n fragmentId,\n data,\n })\n )\n })\n }\n }\n}\n\n/**\n * Stream thunk equivalent to StreamActions.save()\n * Saves data to a specific fragment\n */\nexport const streamSave = (\n fragment: string,\n data: JSONMappable\n): StreamThunk => {\n return (dispatch) => {\n dispatch(\n saveFragment({\n fragmentId: fragment,\n data,\n })\n )\n }\n}\n\nexport const handleStreamMessage = (rawMessage: string): StreamHandleThunk => {\n return (dispatch) => {\n const message = JSON.parse(rawMessage) as StreamMessage\n\n let nextMessage = message\n\n if (message.handler !== 'refresh') {\n message.fragments.reverse().forEach((fragment) => {\n const { id, path } = fragment\n const node = getIn(nextMessage as JSONMappable, path) as JSONMappable\n nextMessage = setIn(nextMessage, path, { __id: id })\n\n dispatch(\n saveFragment({\n fragmentId: id,\n data: node,\n })\n )\n })\n }\n\n if (nextMessage.action === 'handleStreamMessage') {\n if (nextMessage.handler === 'append') {\n dispatch(\n streamAppend(\n nextMessage.fragmentIds,\n nextMessage.data,\n nextMessage.options\n )\n )\n }\n\n if (nextMessage.handler === 'prepend') {\n dispatch(\n streamPrepend(\n nextMessage.fragmentIds,\n nextMessage.data,\n nextMessage.options\n )\n )\n }\n\n if (nextMessage.handler === 'save') {\n dispatch(streamSave(nextMessage.fragmentIds[0], nextMessage.data))\n }\n }\n }\n}\n\nexport const handleStreamResponse = (\n response: StreamResponse\n): StreamHandleThunk => {\n return (dispatch) => {\n let nextResponse = response\n\n nextResponse.fragments.reverse().forEach((fragment) => {\n const { id, path } = fragment\n const node = getIn(nextResponse as JSONMappable, path) as JSONMappable\n nextResponse = setIn(nextResponse, path, { __id: id })\n\n dispatch(\n saveFragment({\n fragmentId: id,\n data: node,\n })\n )\n })\n\n nextResponse.data.forEach((message) => {\n if (message.handler === 'append') {\n dispatch(\n streamAppend(message.fragmentIds, message.data, message.options)\n )\n }\n\n if (message.handler === 'prepend') {\n dispatch(\n streamPrepend(message.fragmentIds, message.data, message.options)\n )\n }\n\n if (message.handler === 'save') {\n dispatch(streamSave(message.fragmentIds[0], message.data))\n }\n })\n }\n}\n"],"mappings":"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","names":["pathQuery","uuidv4"]}
@@ -6132,7 +6132,7 @@ function createArrayProxy(arrayData, fragments, dependencies, proxyCache) {
6132
6132
  }
6133
6133
  if (isArraySetter(prop)) {
6134
6134
  throw new Error(
6135
- `Cannot mutate proxy array. Use Redux actions to update state.`
6135
+ `Cannot mutate proxy array. Use useSetFragment to update state.`
6136
6136
  );
6137
6137
  }
6138
6138
  const index = convertToInt(prop);
@@ -6142,7 +6142,7 @@ function createArrayProxy(arrayData, fragments, dependencies, proxyCache) {
6142
6142
  dependencies.add(item.__id);
6143
6143
  const fragmentData = fragments.current[item.__id];
6144
6144
  if (!fragmentData) {
6145
- throw new Error(`Fragment with id "${item.__id}" not found`);
6145
+ return void 0;
6146
6146
  }
6147
6147
  return createProxy(fragmentData, fragments, dependencies, proxyCache);
6148
6148
  }
@@ -6170,17 +6170,17 @@ function createArrayProxy(arrayData, fragments, dependencies, proxyCache) {
6170
6170
  },
6171
6171
  set() {
6172
6172
  throw new Error(
6173
- "Cannot mutate proxy array. Use Redux actions to update state."
6173
+ "Cannot mutate proxy array. Use useSetFragment to update state."
6174
6174
  );
6175
6175
  },
6176
6176
  deleteProperty() {
6177
6177
  throw new Error(
6178
- "Cannot delete properties on proxy array. Use Redux actions to update state."
6178
+ "Cannot delete properties on proxy array. Use useSetFragment to update state."
6179
6179
  );
6180
6180
  },
6181
6181
  defineProperty() {
6182
6182
  throw new Error(
6183
- "Cannot define properties on proxy array. Use Redux actions to update state."
6183
+ "Cannot define properties on proxy array. Use useSetFragment to update state."
6184
6184
  );
6185
6185
  }
6186
6186
  });
@@ -6203,7 +6203,7 @@ function createObjectProxy(objectData, fragments, dependencies, proxyCache) {
6203
6203
  dependencies.add(value.__id);
6204
6204
  const fragmentData = fragments.current[value.__id];
6205
6205
  if (!fragmentData) {
6206
- throw new Error(`Fragment with id "${value.__id}" not found`);
6206
+ return void 0;
6207
6207
  }
6208
6208
  return createProxy(fragmentData, fragments, dependencies, proxyCache);
6209
6209
  }
@@ -6226,17 +6226,17 @@ function createObjectProxy(objectData, fragments, dependencies, proxyCache) {
6226
6226
  },
6227
6227
  set() {
6228
6228
  throw new Error(
6229
- "Cannot mutate proxy object. Use Redux actions to update state."
6229
+ "Cannot mutate proxy object. Use useSetFragment to update state."
6230
6230
  );
6231
6231
  },
6232
6232
  deleteProperty() {
6233
6233
  throw new Error(
6234
- "Cannot delete properties on proxy object. Use Redux actions to update state."
6234
+ "Cannot delete properties on proxy object. Use useSetFragment to update state."
6235
6235
  );
6236
6236
  },
6237
6237
  defineProperty() {
6238
6238
  throw new Error(
6239
- "Cannot define properties on proxy object. Use Redux actions to update state."
6239
+ "Cannot define properties on proxy object. Use useSetFragment to update state."
6240
6240
  );
6241
6241
  }
6242
6242
  });
@@ -6338,16 +6338,24 @@ the same page. Or if you're sure you want to proceed, use force: true.
6338
6338
  throw new MismatchedComponentError(message);
6339
6339
  }
6340
6340
  }
6341
- dispatch(receiveResponse({ pageKey, response: json }));
6341
+ dispatch(
6342
+ receiveResponse({
6343
+ pageKey,
6344
+ response: JSON.parse(JSON.stringify(json))
6345
+ })
6346
+ );
6342
6347
  const existingPage = createProxy(
6343
6348
  pages[pageKey],
6344
6349
  { current: fragments },
6345
6350
  /* @__PURE__ */ new Set(),
6346
6351
  /* @__PURE__ */ new WeakMap()
6347
6352
  );
6348
- const page = JSON.parse(
6349
- JSON.stringify(beforeSave(existingPage, json))
6350
- );
6353
+ let page = json;
6354
+ if (json.action === "savePage" || json.action === "graft") {
6355
+ page = JSON.parse(
6356
+ JSON.stringify(beforeSave(existingPage, json))
6357
+ );
6358
+ }
6351
6359
  return dispatch(saveAndProcessPage(pageKey, page)).then(() => meta);
6352
6360
  }).catch((e) => handleFetchErr(e, fetchArgs, dispatch));
6353
6361
  };
@@ -6573,7 +6581,7 @@ function saveAndProcessPage(pageKey, page) {
6573
6581
  JSON.stringify(addPlaceholdersToDeferredNodes(existingPage, nextPage))
6574
6582
  );
6575
6583
  }
6576
- page.fragments.reverse().forEach((fragment) => {
6584
+ page.fragments.slice().reverse().forEach((fragment) => {
6577
6585
  const { id, path } = fragment;
6578
6586
  const node = getIn(nextPage, path);
6579
6587
  nextPage = setIn(nextPage, path, { __id: id });
@@ -6624,7 +6632,7 @@ var import_react_redux3 = require("react-redux");
6624
6632
  // lib/hooks/useContent.tsx
6625
6633
  var import_react_redux = require("react-redux");
6626
6634
  var import_react = require("react");
6627
- function useContent(fragmentRef, options) {
6635
+ function useContent(fragmentRef) {
6628
6636
  const superglueState = useSuperglue();
6629
6637
  const currentPageKey = superglueState.currentPageKey;
6630
6638
  const dependencies = (0, import_react.useRef)(/* @__PURE__ */ new Set());
@@ -6649,16 +6657,11 @@ function useContent(fragmentRef, options) {
6649
6657
  });
6650
6658
  }
6651
6659
  );
6652
- const raiseOnMissing = !(options?.optional ?? false);
6653
6660
  const store = (0, import_react_redux.useStore)();
6654
6661
  const proxy = (0, import_react.useMemo)(() => {
6655
6662
  const proxyCache = /* @__PURE__ */ new WeakMap();
6656
6663
  if (fragmentId && !sourceData) {
6657
- if (raiseOnMissing) {
6658
- throw new Error(`Fragment with id "${fragmentId}" not found`);
6659
- } else {
6660
- return void 0;
6661
- }
6664
+ return void 0;
6662
6665
  }
6663
6666
  return createProxy(
6664
6667
  sourceData,
@@ -6666,7 +6669,7 @@ function useContent(fragmentRef, options) {
6666
6669
  dependencies.current,
6667
6670
  proxyCache
6668
6671
  );
6669
- }, [sourceData, trackedFragments, options?.optional]);
6672
+ }, [sourceData, trackedFragments]);
6670
6673
  return proxy;
6671
6674
  }
6672
6675
  function unproxy2(proxy) {
@@ -6676,23 +6679,26 @@ function unproxy2(proxy) {
6676
6679
  // lib/hooks/useSetFragment.tsx
6677
6680
  var import_react_redux2 = require("react-redux");
6678
6681
  var import_immer = require("immer");
6682
+ var immer = new import_immer.Immer();
6683
+ immer.setAutoFreeze(false);
6679
6684
  function useSetFragment() {
6680
6685
  const dispatch = (0, import_react_redux2.useDispatch)();
6681
6686
  const fragments = (0, import_react_redux2.useSelector)((state) => state.fragments);
6682
- return function setter(fragmentRef, updater) {
6683
- const fragmentId = typeof fragmentRef === "string" ? fragmentRef : fragmentRef.__id;
6687
+ function setter(fragmentRefOrId, updater) {
6688
+ const fragmentId = typeof fragmentRefOrId === "string" ? fragmentRefOrId : fragmentRefOrId.__id;
6684
6689
  const currentFragment = fragments[fragmentId];
6685
6690
  if (currentFragment === void 0) {
6686
6691
  throw new Error(`Fragment with id "${fragmentId}" not found`);
6687
6692
  }
6688
- const updatedFragment = (0, import_immer.produce)(currentFragment, updater);
6693
+ const updatedFragment = immer.produce(currentFragment, updater);
6689
6694
  dispatch(
6690
6695
  saveFragment({
6691
6696
  fragmentId,
6692
6697
  data: updatedFragment
6693
6698
  })
6694
6699
  );
6695
- };
6700
+ }
6701
+ return setter;
6696
6702
  }
6697
6703
 
6698
6704
  // lib/hooks/index.ts
@@ -6764,7 +6770,7 @@ function useStreamSource(channel) {
6764
6770
  return () => {
6765
6771
  };
6766
6772
  }
6767
- }, [cable2, channel, currentPageKey]);
6773
+ }, [cable2, JSON.stringify(channel), currentPageKey]);
6768
6774
  return {
6769
6775
  connected,
6770
6776
  subscription: subscriptionRef.current