@thoughtbot/superglue 1.0.2 → 1.0.3
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/.tool-versions +2 -1
- package/dist/action_creators.mjs +1 -1
- package/dist/{chunk-7OMO5P27.mjs → chunk-ENOVWJUC.mjs} +2 -2
- package/dist/chunk-ENOVWJUC.mjs.map +1 -0
- package/dist/cjs/action_creators.cjs +1 -1
- package/dist/cjs/action_creators.cjs.map +1 -1
- package/dist/cjs/superglue.cjs +1 -1
- package/dist/cjs/superglue.cjs.map +1 -1
- package/dist/superglue.mjs +1 -1
- package/dist/superglue.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-7OMO5P27.mjs.map +0 -1
package/.tool-versions
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
|
|
1
|
+
ruby 3.1.7
|
|
2
|
+
nodejs 20.18.1
|
package/dist/action_creators.mjs
CHANGED
|
@@ -274,7 +274,7 @@ function argsForFetch(getState, pathQuery2, {
|
|
|
274
274
|
return [fetchPath.toString(), { ...options, ...rest }];
|
|
275
275
|
}
|
|
276
276
|
function extractJSON(rsp) {
|
|
277
|
-
return rsp.json().then((json) => {
|
|
277
|
+
return rsp.clone().json().then((json) => {
|
|
278
278
|
return { rsp, json };
|
|
279
279
|
}).catch((e) => {
|
|
280
280
|
e.response = rsp;
|
|
@@ -743,4 +743,4 @@ export {
|
|
|
743
743
|
visit,
|
|
744
744
|
saveAndProcessPage
|
|
745
745
|
};
|
|
746
|
-
//# sourceMappingURL=chunk-
|
|
746
|
+
//# sourceMappingURL=chunk-ENOVWJUC.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/utils/url.ts","../lib/utils/helpers.ts","../lib/utils/immutability.ts","../lib/config.ts","../lib/utils/request.ts","../lib/utils/ujs.ts","../lib/utils/window.ts","../lib/actions.ts","../lib/action_creators/requests.ts","../lib/action_creators/index.ts"],"sourcesContent":["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","import { GraftResponse, HistoryState, VisitResponse } from '../types'\nimport { urlToPageKey } from './url'\n\nexport function isGraft(page: GraftResponse | VisitResponse): boolean {\n return 'action' in page && page.action === 'graft'\n}\n\nexport function extractNodeAndPath(page: GraftResponse): {\n node: unknown\n pathToNode: string\n} {\n const { data: node, action, path: pathToNode } = page\n\n if (action === 'graft') {\n return { node, pathToNode }\n } else {\n const errMsg =\n 'Expected page to be a graft response rendered from node filtering.'\n throw new Error(errMsg)\n }\n}\n\nexport function argsForHistory(path: string): [string, HistoryState] {\n const pageKey = urlToPageKey(path)\n\n return [\n path,\n {\n superglue: true,\n pageKey,\n posX: 0,\n posY: 0,\n },\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","import { formatForXHR } from './url'\nimport { config } from '../config'\nimport { BasicRequestInit, ParsedResponse, RootState } from '../types'\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 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 .clone()\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","import {\n Handlers,\n UJSHandlers,\n SuperglueStore,\n ApplicationVisit,\n ApplicationRemote,\n RemoteProps,\n VisitProps,\n} from '../types'\n\nexport class HandlerBuilder {\n public attributePrefix: string\n public visit: ApplicationVisit\n public remote: ApplicationRemote\n private store: SuperglueStore\n\n constructor({\n ujsAttributePrefix,\n visit,\n remote,\n store,\n }: {\n ujsAttributePrefix: string\n visit: ApplicationVisit\n remote: ApplicationRemote\n store: SuperglueStore\n }) {\n this.attributePrefix = ujsAttributePrefix\n this.isUJS = this.isUJS.bind(this)\n this.store = store\n\n this.handleSubmit = this.handleSubmit.bind(this)\n this.handleClick = this.handleClick.bind(this)\n\n this.visit = visit\n this.remote = remote\n this.visitOrRemote = this.visitOrRemote.bind(this)\n }\n\n retrieveLink(target: Element): HTMLAnchorElement | undefined {\n const link = target.closest<HTMLAnchorElement>('a')\n if (link && link.href.length !== 0) {\n return link\n }\n }\n\n isNonStandardClick(\n event: React.MouseEvent<HTMLDivElement, MouseEvent>\n ): boolean {\n return (\n event.button > 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n )\n }\n\n isUJS(node: HTMLFormElement | HTMLAnchorElement): boolean {\n const hasVisit = !!node.getAttribute(this.attributePrefix + '-visit')\n const hasRemote = !!node.getAttribute(this.attributePrefix + '-remote')\n\n return hasVisit || hasRemote\n }\n\n handleSubmit(event: React.FormEvent<HTMLDivElement>): void {\n const form = event.target\n\n if (!(form instanceof HTMLFormElement)) {\n return\n }\n\n if (!this.isUJS(form)) {\n return\n }\n\n event.preventDefault()\n\n const url = form.getAttribute('action')\n if (!url) {\n return\n }\n\n const method = (form.getAttribute('method') || 'POST').toUpperCase()\n\n this.visitOrRemote(form, url, {\n method,\n body: new FormData(form),\n })\n }\n\n handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>): void {\n if (!(event.target instanceof Element)) {\n return\n }\n\n const link = this.retrieveLink(event.target)\n const isNonStandard = this.isNonStandardClick(event)\n if (!link || isNonStandard || !this.isUJS(link)) {\n return\n }\n\n event.preventDefault()\n const url = link.getAttribute('href')\n if (!url) {\n return\n }\n\n this.visitOrRemote(link, url, { method: 'GET' })\n }\n\n visitOrRemote(\n linkOrForm: HTMLAnchorElement | HTMLFormElement,\n url: string,\n opts: RemoteProps | VisitProps\n ): void {\n const dataset = { ...linkOrForm.dataset }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-visit')) {\n this.visit(url, { ...opts, dataset })\n }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-remote')) {\n const { currentPageKey } = this.store.getState().superglue\n this.remote(url, {\n ...opts,\n pageKey: currentPageKey,\n dataset,\n })\n }\n }\n\n handlers(): Handlers {\n return {\n onClick: this.handleClick,\n onSubmit: this.handleSubmit,\n }\n }\n}\n\nexport const ujsHandlers: UJSHandlers = ({\n ujsAttributePrefix,\n visit,\n remote,\n store,\n}) => {\n const builder = new HandlerBuilder({\n visit,\n remote,\n ujsAttributePrefix,\n store,\n })\n\n return builder.handlers()\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 VisitResponse,\n JSONMappable,\n Keypath,\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: VisitResponse }) => {\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 called whenever a fragment is received from `visit` or updated\n * using `remote`. Its a useful action to use for cross cutting concerns like a\n * shared header or a shopping cart. For example:\n *\n * ```\n * import { updateFragments } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(updateFragments, (state, action) => {\n * // Update the slice using the latest and greatest.\n * return action.value\n * ```\n */\nexport const updateFragments = createAction<{\n name: string\n path: Keypath\n pageKey: PageKey\n value: JSONMappable\n previousValue?: JSONMappable\n}>('@@superglue/UPDATE_FRAGMENTS')\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","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} from '../actions'\nimport { saveAndProcessPage } from './index'\nimport {\n FetchArgs,\n VisitResponse,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n NavigationAction,\n VisitMeta,\n} from '../types'\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(superglueError({ message: err.message }))\n throw err\n}\n\nfunction buildMeta(\n pageKey: string,\n page: VisitResponse,\n state: SuperglueState,\n rsp: Response,\n fetchArgs: FetchArgs\n): Meta {\n const { assets: prevAssets } = state\n const { assets: nextAssets } = page\n\n return {\n pageKey,\n page,\n redirected: rsp.redirected,\n rsp,\n fetchArgs,\n componentIdentifier: page.componentIdentifier,\n needsRefresh: needsRefresh(prevAssets, nextAssets),\n }\n}\n\nexport class MismatchedComponentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MismatchedComponentError'\n }\n}\n\nexport const remote: RemoteCreator = (\n path,\n {\n pageKey: targetPageKey,\n force = false,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\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 = {} } = 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 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 const page = beforeSave(pages[pageKey], json)\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 = {} } = getState()\n const isGet = fetchArgs[1].method === 'GET'\n const pageKey = calculatePageKey(rsp, isGet, currentPageKey)\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 meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n const visitMeta: VisitMeta = {\n ...meta,\n navigationAction: calculateNavAction(\n meta,\n rsp,\n isGet,\n pageKey,\n currentPageKey,\n revisit\n ),\n }\n\n const page = beforeSave(pages[pageKey], json)\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 isGet: boolean,\n pageKey: string,\n currentPageKey: string,\n revisit: boolean\n) {\n let navigationAction: NavigationAction = 'push'\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 { urlToPageKey, getIn, propsAtParam } from '../utils'\nimport {\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n updateFragments,\n handleGraft,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n VisitResponse,\n SaveAndProcessPageThunk,\n DefermentThunk,\n GraftResponse,\n Defer,\n JSONMappable,\n} from '../types'\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\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: VisitResponse | GraftResponse\n): SaveAndProcessPageThunk {\n return (dispatch, getState) => {\n pageKey = urlToPageKey(pageKey)\n\n const { defers = [] } = page\n\n if ('action' in page) {\n const prevPage = getState().pages[pageKey]\n dispatch(handleGraft({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n // A fragment only works on a block in props_template. So using getIn\n // will always return a JSONMappable\n const currentFragment = getIn(currentPage, path) as JSONMappable\n const prevFragment = getIn(prevPage, path) as JSONMappable\n if (!prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n } else if (currentFragment !== prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n previousValue: prevFragment,\n path,\n })\n )\n }\n })\n } else {\n dispatch(saveResponse({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n const currentFragment = getIn(currentPage, path) as JSONMappable\n\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n })\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, defers)).then(() =>\n Promise.resolve()\n )\n } else {\n return Promise.resolve()\n }\n }\n}\n"],"mappings":"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","names":["pathQuery","visit","remote"]}
|
|
@@ -250,7 +250,7 @@ function argsForFetch(getState, pathQuery2, {
|
|
|
250
250
|
return [fetchPath.toString(), { ...options, ...rest }];
|
|
251
251
|
}
|
|
252
252
|
function extractJSON(rsp) {
|
|
253
|
-
return rsp.json().then((json) => {
|
|
253
|
+
return rsp.clone().json().then((json) => {
|
|
254
254
|
return { rsp, json };
|
|
255
255
|
}).catch((e) => {
|
|
256
256
|
e.response = rsp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../lib/action_creators/index.ts","../../lib/utils/url.ts","../../lib/utils/immutability.ts","../../lib/config.ts","../../lib/utils/request.ts","../../lib/utils/window.ts","../../lib/actions.ts","../../lib/action_creators/requests.ts"],"sourcesContent":["import { urlToPageKey, getIn, propsAtParam } from '../utils'\nimport {\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n updateFragments,\n handleGraft,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n VisitResponse,\n SaveAndProcessPageThunk,\n DefermentThunk,\n GraftResponse,\n Defer,\n JSONMappable,\n} from '../types'\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\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: VisitResponse | GraftResponse\n): SaveAndProcessPageThunk {\n return (dispatch, getState) => {\n pageKey = urlToPageKey(pageKey)\n\n const { defers = [] } = page\n\n if ('action' in page) {\n const prevPage = getState().pages[pageKey]\n dispatch(handleGraft({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n // A fragment only works on a block in props_template. So using getIn\n // will always return a JSONMappable\n const currentFragment = getIn(currentPage, path) as JSONMappable\n const prevFragment = getIn(prevPage, path) as JSONMappable\n if (!prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n } else if (currentFragment !== prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n previousValue: prevFragment,\n path,\n })\n )\n }\n })\n } else {\n dispatch(saveResponse({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n const currentFragment = getIn(currentPage, path) as JSONMappable\n\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n })\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, 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","import { formatForXHR } from './url'\nimport { config } from '../config'\nimport { BasicRequestInit, ParsedResponse, RootState } from '../types'\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 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 VisitResponse,\n JSONMappable,\n Keypath,\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: VisitResponse }) => {\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 called whenever a fragment is received from `visit` or updated\n * using `remote`. Its a useful action to use for cross cutting concerns like a\n * shared header or a shopping cart. For example:\n *\n * ```\n * import { updateFragments } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(updateFragments, (state, action) => {\n * // Update the slice using the latest and greatest.\n * return action.value\n * ```\n */\nexport const updateFragments = createAction<{\n name: string\n path: Keypath\n pageKey: PageKey\n value: JSONMappable\n previousValue?: JSONMappable\n}>('@@superglue/UPDATE_FRAGMENTS')\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","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} from '../actions'\nimport { saveAndProcessPage } from './index'\nimport {\n FetchArgs,\n VisitResponse,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n NavigationAction,\n VisitMeta,\n} from '../types'\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(superglueError({ message: err.message }))\n throw err\n}\n\nfunction buildMeta(\n pageKey: string,\n page: VisitResponse,\n state: SuperglueState,\n rsp: Response,\n fetchArgs: FetchArgs\n): Meta {\n const { assets: prevAssets } = state\n const { assets: nextAssets } = page\n\n return {\n pageKey,\n page,\n redirected: rsp.redirected,\n rsp,\n fetchArgs,\n componentIdentifier: page.componentIdentifier,\n needsRefresh: needsRefresh(prevAssets, nextAssets),\n }\n}\n\nexport class MismatchedComponentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MismatchedComponentError'\n }\n}\n\nexport const remote: RemoteCreator = (\n path,\n {\n pageKey: targetPageKey,\n force = false,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\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 = {} } = 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 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 const page = beforeSave(pages[pageKey], json)\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 = {} } = getState()\n const isGet = fetchArgs[1].method === 'GET'\n const pageKey = calculatePageKey(rsp, isGet, currentPageKey)\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 meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n const visitMeta: VisitMeta = {\n ...meta,\n navigationAction: calculateNavAction(\n meta,\n rsp,\n isGet,\n pageKey,\n currentPageKey,\n revisit\n ),\n }\n\n const page = beforeSave(pages[pageKey], json)\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 isGet: boolean,\n pageKey: string,\n currentPageKey: string,\n revisit: boolean\n) {\n let navigationAction: NavigationAction = 'push'\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"],"mappings":"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","names":["pathQuery"]}
|
|
1
|
+
{"version":3,"sources":["../../lib/action_creators/index.ts","../../lib/utils/url.ts","../../lib/utils/immutability.ts","../../lib/config.ts","../../lib/utils/request.ts","../../lib/utils/window.ts","../../lib/actions.ts","../../lib/action_creators/requests.ts"],"sourcesContent":["import { urlToPageKey, getIn, propsAtParam } from '../utils'\nimport {\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n updateFragments,\n handleGraft,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n VisitResponse,\n SaveAndProcessPageThunk,\n DefermentThunk,\n GraftResponse,\n Defer,\n JSONMappable,\n} from '../types'\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\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: VisitResponse | GraftResponse\n): SaveAndProcessPageThunk {\n return (dispatch, getState) => {\n pageKey = urlToPageKey(pageKey)\n\n const { defers = [] } = page\n\n if ('action' in page) {\n const prevPage = getState().pages[pageKey]\n dispatch(handleGraft({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n // A fragment only works on a block in props_template. So using getIn\n // will always return a JSONMappable\n const currentFragment = getIn(currentPage, path) as JSONMappable\n const prevFragment = getIn(prevPage, path) as JSONMappable\n if (!prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n } else if (currentFragment !== prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n previousValue: prevFragment,\n path,\n })\n )\n }\n })\n } else {\n dispatch(saveResponse({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n const currentFragment = getIn(currentPage, path) as JSONMappable\n\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n })\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, 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","import { formatForXHR } from './url'\nimport { config } from '../config'\nimport { BasicRequestInit, ParsedResponse, RootState } from '../types'\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 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 .clone()\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 VisitResponse,\n JSONMappable,\n Keypath,\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: VisitResponse }) => {\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 called whenever a fragment is received from `visit` or updated\n * using `remote`. Its a useful action to use for cross cutting concerns like a\n * shared header or a shopping cart. For example:\n *\n * ```\n * import { updateFragments } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(updateFragments, (state, action) => {\n * // Update the slice using the latest and greatest.\n * return action.value\n * ```\n */\nexport const updateFragments = createAction<{\n name: string\n path: Keypath\n pageKey: PageKey\n value: JSONMappable\n previousValue?: JSONMappable\n}>('@@superglue/UPDATE_FRAGMENTS')\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","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} from '../actions'\nimport { saveAndProcessPage } from './index'\nimport {\n FetchArgs,\n VisitResponse,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n NavigationAction,\n VisitMeta,\n} from '../types'\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(superglueError({ message: err.message }))\n throw err\n}\n\nfunction buildMeta(\n pageKey: string,\n page: VisitResponse,\n state: SuperglueState,\n rsp: Response,\n fetchArgs: FetchArgs\n): Meta {\n const { assets: prevAssets } = state\n const { assets: nextAssets } = page\n\n return {\n pageKey,\n page,\n redirected: rsp.redirected,\n rsp,\n fetchArgs,\n componentIdentifier: page.componentIdentifier,\n needsRefresh: needsRefresh(prevAssets, nextAssets),\n }\n}\n\nexport class MismatchedComponentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MismatchedComponentError'\n }\n}\n\nexport const remote: RemoteCreator = (\n path,\n {\n pageKey: targetPageKey,\n force = false,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\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 = {} } = 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 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 const page = beforeSave(pages[pageKey], json)\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 = {} } = getState()\n const isGet = fetchArgs[1].method === 'GET'\n const pageKey = calculatePageKey(rsp, isGet, currentPageKey)\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 meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n const visitMeta: VisitMeta = {\n ...meta,\n navigationAction: calculateNavAction(\n meta,\n rsp,\n isGet,\n pageKey,\n currentPageKey,\n revisit\n ),\n }\n\n const page = beforeSave(pages[pageKey], json)\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 isGet: boolean,\n pageKey: string,\n currentPageKey: string,\n revisit: boolean\n) {\n let navigationAction: NavigationAction = 'push'\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"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,IAAM,cAAc;AAEb,SAAS,UAAU,KAAqB;AAC7C,QAAM,EAAE,UAAU,QAAQ,MAAM,IAAI,IAAI,IAAI,KAAK,WAAW;AAE5D,SAAO,WAAW;AACpB;AAQO,SAAS,WAAW,KAAsB;AAC/C,QAAM,EAAE,aAAa,IAAI,IAAI,IAAI,KAAK,WAAW;AAEjD,SAAO,aAAa,IAAI,UAAU;AACpC;AAEO,SAAS,aAAa,KAA4B;AACvD,QAAM,EAAE,aAAa,IAAI,IAAI,IAAI,KAAK,WAAW;AAEjD,SAAO,aAAa,IAAI,UAAU;AACpC;AAEO,SAAS,eAAe,KAAqB;AAClD,QAAM,SAAS,IAAI,IAAI,KAAK,WAAW;AACvC,SAAO,aAAa,IAAI,UAAU,MAAM;AAExC,SAAO,OAAO,KAAK,QAAQ,OAAO,QAAQ,EAAE;AAC9C;AAEO,SAAS,cAAc,KAAqB;AACjD,QAAM,SAAS,IAAI,IAAI,KAAK,WAAW;AACvC,SAAO,aAAa,OAAO,UAAU;AAErC,SAAO,OAAO,KAAK,QAAQ,OAAO,QAAQ,EAAE;AAC9C;AAQO,SAAS,aAAa,KAAsB;AACjD,QAAM,SAAS,IAAI,IAAI,KAAK,WAAW;AACvC,SAAO,aAAa,OAAO,UAAU;AACrC,SAAO,aAAa,OAAO,QAAQ;AAEnC,SAAO,UAAU,OAAO,SAAS,CAAC;AACpC;AAEO,SAAS,YAAY,KAAqB;AAC/C,QAAM,SAAS,IAAI,IAAI,KAAK,WAAW;AACvC,SAAO,OAAO;AAEd,SAAO,OAAO,KAAK,QAAQ,OAAO,QAAQ,EAAE;AAC9C;AAEO,SAAS,aAAa,KAAqB;AAChD,QAAM,UAAU,CAAC,aAAa,cAAc;AAE5C,SAAO,QAAQ,OAAO,CAAC,MAAM,MAAM,EAAE,IAAI,GAAG,GAAG;AACjD;;;AC9DA,IAAM,eAAe;AAErB,IAAM,eAAN,cAA2B,MAAM;AAAA,EAC/B,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AASA,SAAS,MAAM,MAAoB,MAA0B;AAC3D,QAAM,UAAU,iBAAiB,IAAI;AACrC,MAAI,SAAoB;AACxB,MAAI;AAEJ,OAAK,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACnC,UAAM,MAAM,QAAQ,CAAC;AAErB,QAAI,OAAO,WAAW,YAAY,WAAW,MAAM;AACjD,UAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,aAAa,KAAK,GAAG,GAAG;AACpD,cAAM,IAAI;AAAA,UACR,iDAAiD,GAAG;AAAA,QACtD;AAAA,MACF;AAEA,eAAS,MAAM,QAAQ,GAAG;AAAA,IAC5B,OAAO;AACL,YAAM,IAAI;AAAA,QACR,6CAA6C,KAAK,UAAU,MAAM,CAAC;AAAA,MACrE;AAAA,IACF;AAAA,EACF;AAEA,MAAI,MAAM,QAAQ,QAAQ;AACxB,WAAO;AAAA,EACT,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAMA,SAAS,OAAO,MAAoB,KAAsC;AACxE,MAAI,MAAM,QAAQ,IAAI,KAAK,OAAO,MAAM,OAAO,GAAG,CAAC,GAAG;AACpD,UAAM,YAAY,MAAM,KAAK,IAAI,MAAM,GAAG,CAAC;AAC3C,UAAM,OAAO,UAAU,CAAC;AACxB,UAAM,KAAK,UAAU,CAAC;AAEtB,QAAI,CAAC,MAAM,CAAC,MAAM;AAChB,aAAO;AAAA,IACT;AAEA,QAAI;AACJ,QAAI;AAEJ,SAAK,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAChC,cAAQ,KAAK,CAAC;AACd,UACE,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,KACpB,UAAU,MACV;AACA,cAAM,MAAM,MAAM,IAAI;AACtB,YAAI,OAAO,IAAI,SAAS,MAAM,IAAI;AAChC;AAAA,QACF;AAAA,MACF,OAAO;AACL,cAAM,IAAI,aAAa,wBAAwB,GAAG,OAAO,KAAK,EAAE;AAAA,MAClE;AAAA,IACF;AAEA,QAAI,MAAM,KAAK,QAAQ;AACrB,YAAM,IAAI,aAAa,kBAAkB,GAAG,sBAAsB;AAAA,IACpE;AAEA,WAAO;AAAA,EACT,OAAO;AACL,WAAO;AAAA,EACT;AACF;AAEA,SAAS,MAAM,MAAoB,KAAa;AAC9C,QAAM,YAAY,OAAO,MAAM,GAAG;AAElC,MAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,WAAO,KAAK,SAAmB;AAAA,EACjC,OAAO;AACL,WAAO,KAAK,SAAS;AAAA,EACvB;AACF;AAEA,SAAS,iBAAiB,MAAwB;AAChD,MAAI,OAAO,SAAS,UAAU;AAC5B,WAAO,KAAK,QAAQ,MAAM,EAAE;AAC5B,QAAI,SAAS,IAAI;AACf,aAAO,CAAC;AAAA,IACV;AAEA,WAAO,KAAK,MAAM,GAAG;AAAA,EACvB,OAAO;AACL,WAAO;AAAA,EACT;AACF;;;ACnHO,IAAM,SAAS;AAAA,EACpB,SAAS;AAAA,EACT,UAAU;AACZ;;;ACCO,SAAS,gBAAgB,KAAwB;AACtD,SAAO,eAAe,GAAG,KAAK,CAAC,gBAAgB,GAAG;AACpD;AAEO,SAAS,eAAe,KAAwB;AACrD,QAAM,cAAc,IAAI,QAAQ,IAAI,cAAc;AAClD,QAAM,YAAY;AAElB,SAAO,CAAC,EAAE,eAAe,YAAY,MAAM,SAAS;AACtD;AAEA,SAAS,gBAAgB,KAAwB;AAC/C,QAAM,cAAc,IAAI,QAAQ,IAAI,qBAAqB;AAEzD,SAAO,CAAC,EAAE,eAAe,YAAY,MAAM,aAAa,MAAM;AAChE;AAEA,IAAM,yBAAN,cAAqC,MAAM;AAAA,EAGzC,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,iBAAiB,MAAsC;AACrE,QAAM,EAAE,IAAI,IAAI;AAChB,MAAI,gBAAgB,GAAG,GAAG;AACxB,WAAO;AAAA,EACT,OAAO;AACL,UAAM,QAAQ,IAAI,uBAAuB,4BAA4B;AACrE,UAAM,WAAW;AACjB,UAAM;AAAA,EACR;AACF;AAEO,SAAS,mBAAmB,MAAsC;AACvE,QAAM,EAAE,IAAI,IAAI;AAChB,MAAI,CAAC,IAAI,MAAM,IAAI,WAAW,KAAK;AACjC,QAAI,IAAI,WAAW,KAAK;AACtB,cAAQ;AAAA,QACN;AAAA,MAMF;AAAA,IACF;AACA,UAAM,QAAQ,IAAI,uBAAuB,IAAI,UAAU;AACvD,UAAM,WAAW;AACjB,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAEO,SAAS,aACd,UACAA,YACA;AAAA,EACE,SAAS;AAAA,EACT,UAAU,CAAC;AAAA,EACX,OAAO;AAAA,EACP;AAAA,EACA,GAAG;AACL,IAAsB,CAAC,GACK;AAC5B,WAAS,OAAO,YAAY;AAC5B,QAAM,eAAe,SAAS,EAAE;AAEhC,QAAM,cAAc,EAAE,GAAG,QAAQ;AACjC,cAAY,kBAAkB,IAAI;AAClC,cAAY,QAAQ,IAAI;AACxB,cAAY,qBAAqB,IAAI;AAErC,MAAI,UAAU,SAAS,UAAU,QAAQ;AACvC,gBAAY,cAAc,IAAI;AAAA,EAChC;AAEA,MAAI,gBAAgB,UAAU;AAC5B,WAAO,YAAY,cAAc;AAAA,EACnC;AAEA,MAAI,aAAa,WAAW;AAC1B,gBAAY,cAAc,IAAI,aAAa;AAAA,EAC7C;AAEA,QAAM,YAAY,IAAI,IAAI,aAAaA,UAAS,GAAG,OAAO,OAAO;AAEjE,QAAM,cAAc;AAEpB,MAAI,EAAE,UAAU,SAAS,UAAU,SAAS;AAC1C,gBAAY,wBAAwB,IAAI;AACxC,aAAS;AAAA,EACX;AAEA,QAAM,UAA4B;AAAA,IAChC;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,MAAI,aAAa,gBAAgB;AAC/B,UAAM,WAAW,IAAI,IAAI,aAAa,gBAAgB,OAAO,OAAO;AAEpE,YAAQ,WAAW,SAAS,SAAS;AAAA,EACvC;AAEA,MAAI,UAAU,SAAS,UAAU,QAAQ;AACvC,QAAI,QAAQ,gBAAgB,UAAU;AACpC,YAAM,UAAU,IAAI;AAAA,QAClB,QAAQ;AAAA,MACV;AAKA,cAAQ,QAAQ,CAAC,OAAO,QAAQ,UAAU,aAAa,OAAO,GAAG,CAAC;AAClE,cAAQ,QAAQ,CAAC,OAAO,QAAQ,UAAU,aAAa,OAAO,KAAK,KAAK,CAAC;AAAA,IAC3E;AAEA,WAAO,QAAQ;AAAA,EACjB;AAEA,SAAO,CAAC,UAAU,SAAS,GAAG,EAAE,GAAG,SAAS,GAAG,KAAK,CAAC;AACvD;AAEO,SAAS,YAAY,KAA4C;AACtE,SAAO,IACJ,MAAM,EACN,KAAK,EACL,KAAK,CAAC,SAAS;AACd,WAAO,EAAE,KAAK,KAAK;AAAA,EACrB,CAAC,EACA,MAAM,CAAC,MAAM;AACZ,MAAE,WAAW;AACb,UAAM;AAAA,EACR,CAAC;AACL;AAEO,SAAS,cAAc,KAA4C;AACxE,SAAO,QAAQ,QAAQ,GAAG,EACvB,KAAK,WAAW,EAChB,KAAK,kBAAkB,EACvB,KAAK,gBAAgB;AAC1B;;;ACxJO,SAAS,aACd,YACA,WACS;AACT,MAAI,cAAc,WAAW;AAC3B,UAAM,eAAe,CAAC,UAAU,MAAM,CAAC,UAAU,WAAW,SAAS,KAAK,CAAC;AAC3E,WAAO;AAAA,EACT,OAAO;AACL,WAAO;AAAA,EACT;AACF;;;ACVA,qBAA6B;AAWtB,IAAM,iBAAiB;AACvB,IAAM,mBAAmB;AAEzB,IAAM,mBAAe;AAAA,EAC1B;AAAA,EACA,CAAC,EAAE,SAAS,KAAK,MAAgD;AAC/D,cAAU,aAAa,OAAO;AAE9B,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,kBAAc;AAAA,EACzB;AAAA,EACA,CAAC,EAAE,SAAS,KAAK,MAAgD;AAC/D,cAAU,aAAa,OAAO;AAE9B,WAAO;AAAA,MACL,SAAS;AAAA,QACP;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,qBAAiB;AAAA,EAC5B;AACF;AAmBO,IAAM,sBAAkB,6BAM5B,8BAA8B;AAgB1B,IAAM,eAAW;AAAA,EACtB;AACF;AAWO,IAAM,iBAAa;AAAA,EACxB;AACF;AAgBO,IAAM,kBAAc;AAAA,EACzB;AACF;AAgBO,IAAM,kBAAc,6BAGxB,0BAA0B;AAgBtB,IAAM,mBAAe,6BAGzB,2BAA2B;AAEvB,IAAM,mBAAe,6BAEzB,4BAA4B;AAExB,IAAM,oBAAgB,6BAE1B,4BAA4B;AAExB,IAAM,oBAAgB,6BAE1B,6BAA6B;;;ACzIhC,SAAS,eACP,KACA,WACA,UACO;AACP,WAAS,eAAe,EAAE,SAAS,IAAI,QAAQ,CAAC,CAAC;AACjD,QAAM;AACR;AAEA,SAAS,UACP,SACA,MACA,OACA,KACA,WACM;AACN,QAAM,EAAE,QAAQ,WAAW,IAAI;AAC/B,QAAM,EAAE,QAAQ,WAAW,IAAI;AAE/B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY,IAAI;AAAA,IAChB;AAAA,IACA;AAAA,IACA,qBAAqB,KAAK;AAAA,IAC1B,cAAc,aAAa,YAAY,UAAU;AAAA,EACnD;AACF;AAEO,IAAM,2BAAN,cAAuC,MAAM;AAAA,EAClD,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,IAAM,SAAwB,CACnC,MACA;AAAA,EACE,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,aAAa,CAAC,UAAgB,iBAA+B;AAAA,EAC7D,GAAG;AACL,IAAI,CAAC,MACF;AACH,kBAAgB,iBAAiB,aAAa,aAAa;AAE3D,SAAO,CAAC,UAAU,aAAa;AAC7B,UAAM,YAAY,aAAa,UAAU,MAAM,IAAI;AACnD,UAAM,iBAAiB,SAAS,EAAE,UAAU;AAE5C,aAAS,aAAa,EAAE,gBAAgB,UAAU,CAAC,CAAC;AACpD,aAAS,YAAY,EAAE,UAAU,CAAC,CAAC;AAEnC,WAAO,MAAM,GAAG,SAAS,EACtB,KAAK,aAAa,EAClB,KAAK,CAAC,EAAE,KAAK,KAAK,MAAM;AACvB,YAAM,EAAE,WAAW,QAAQ,CAAC,EAAE,IAAI,SAAS;AAE3C,UAAI;AACJ,UAAI,kBAAkB,QAAW;AAC/B,cAAM,QAAQ,UAAU,CAAC,EAAE,WAAW;AACtC,kBAAU,iBAAiB,KAAK,OAAO,cAAc;AAAA,MACvD,OAAO;AACL,kBAAU;AAAA,MACZ;AAEA,YAAM,OAAO,UAAU,SAAS,MAAM,WAAW,KAAK,SAAS;AAE/D,YAAM,aAAa,MAAM,OAAO,GAAG;AACnC,YAAM,aAAa,KAAK;AACxB,UAAI,CAAC,CAAC,cAAc,cAAc,cAAc,CAAC,OAAO;AACtD,cAAM,UAAU;AAAA,oBACN,cAAc;AAAA,MAC5B,UAAU;AAAA,0BACU,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAOjC,UAAU,QAAQ,aAAa,IAAI,CAAC,WAAW,UAAU;AAAA,sDACN,UAAU;AAAA;AAAA;AAAA;AAAA;AAKtD,cAAM,IAAI,yBAAyB,OAAO;AAAA,MAC5C;AAEA,YAAM,OAAO,WAAW,MAAM,OAAO,GAAG,IAAI;AAC5C,aAAO,SAAS,mBAAmB,SAAS,IAAI,CAAC,EAAE,KAAK,MAAM,IAAI;AAAA,IACpE,CAAC,EACA,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,QAAQ,CAAC;AAAA,EACxD;AACF;AAEA,IAAI,sBAAsB;AAAA;AAAA,EAExB,OAAO,CAAC,YAAoB;AAAA,EAE5B;AACF;AAEO,IAAM,QAAsB,CACjC,MACA;AAAA,EACE;AAAA,EACA,aAAa,CAAC,UAAgB,iBAA+B;AAAA,EAC7D,UAAU;AAAA,EACV,GAAG;AACL,IAAI,CAAC,MACF;AACH,SAAO,CAAC,UAAU,aAAa;AAC7B,UAAM,iBAAiB,SAAS,EAAE,UAAU;AAC5C,qBACG,kBAAkB,aAAa,cAAc,KAAM;AACtD,UAAM,iBAAiB,kBAAkB,SAAS,EAAE;AAEpD,QAAI,WAAW,IAAI,KAAK,CAAC,gBAAgB;AACvC,cAAQ;AAAA,QACN,uCAAuC,cAAc;AAAA,MACvD;AACA,aAAO,cAAc,IAAI;AAAA,IAC3B;AAEA,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,EAAE,OAAO,IAAI;AACnB,UAAM,YAAY,aAAa,UAAU,MAAM;AAAA,MAC7C,GAAG;AAAA,MACH;AAAA,IACF,CAAC;AAED,aAAS,YAAY,EAAE,gBAAgB,UAAU,CAAC,CAAC;AACnD,aAAS,YAAY,EAAE,UAAU,CAAC,CAAC;AAEnC,wBAAoB;AAAA,MAClB;AAAA,IACF;AACA,0BAAsB;AAEtB,WAAO,MAAM,GAAG,SAAS,EACtB,KAAK,aAAa,EAClB,KAAK,CAAC,EAAE,KAAK,KAAK,MAAM;AACvB,YAAM,EAAE,WAAW,QAAQ,CAAC,EAAE,IAAI,SAAS;AAC3C,YAAM,QAAQ,UAAU,CAAC,EAAE,WAAW;AACtC,YAAM,UAAU,iBAAiB,KAAK,OAAO,cAAc;AAC3D,UAAI,kBAAkB,WAAW,IAAI,KAAK,gBAAgB;AACxD,cAAM,aAAa,MAAM,cAAc,GAAG;AAC1C,cAAM,aAAa,KAAK;AACxB,YAAI,CAAC,CAAC,cAAc,cAAc,YAAY;AAC5C,gBAAM,UAAU;AAAA,uBACL,UAAU;AAAA,uBACV,UAAU,gBAAgB,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAO5D,UAAU,QAAQ,aAAa,IAAI,CAAC,WAAW,UAAU;AAAA,sDACN,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAMpD,gBAAM,IAAI,yBAAyB,OAAO;AAAA,QAC5C;AACA,iBAAS,SAAS,EAAE,MAAM,gBAAgB,IAAI,QAAQ,CAAC,CAAC;AAAA,MAC1D;AAEA,YAAM,OAAO,UAAU,SAAS,MAAM,WAAW,KAAK,SAAS;AAE/D,YAAM,YAAuB;AAAA,QAC3B,GAAG;AAAA,QACH,kBAAkB;AAAA,UAChB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,YAAM,OAAO,WAAW,MAAM,OAAO,GAAG,IAAI;AAC5C,aAAO,SAAS,mBAAmB,SAAS,IAAI,CAAC,EAAE,KAAK,MAAM,SAAS;AAAA,IACzE,CAAC,EACA,MAAM,CAAC,MAAM,eAAe,GAAG,WAAW,QAAQ,CAAC;AAAA,EACxD;AACF;AAEA,SAAS,mBACP,MACA,KACA,OACA,SACA,gBACA,SACA;AACA,MAAI,mBAAqC;AACzC,MAAI,CAAC,IAAI,cAAc,CAAC,OAAO;AAC7B,uBAAmB;AAAA,EACrB;AACA,QAAM,aAAa,WAAW;AAC9B,MAAI,YAAY;AACd,uBAAmB;AAAA,EACrB;AACA,MAAI,WAAW,OAAO;AACpB,QAAI,IAAI,YAAY;AAClB,yBAAmB;AAAA,IACrB,OAAO;AACL,yBAAmB;AAAA,IACrB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,iBACP,KACA,OACA,gBACA;AACA,MAAI,UAAU,aAAa,IAAI,GAAG;AAClC,MAAI,CAAC,SAAS,CAAC,IAAI,YAAY;AAC7B,cAAU;AAAA,EACZ;AAEA,QAAM,kBAAkB,IAAI,QAAQ,IAAI,kBAAkB;AAC1D,MAAI,iBAAiB;AACnB,cAAU,aAAa,eAAe;AAAA,EACxC;AACA,SAAO;AACT;;;APzPA,SAAS,gBACP,SACA,SAAkB,CAAC,GACH;AAChB,YAAU,aAAa,OAAO;AAC9B,SAAO,CAAC,aAAa;AACnB,UAAM,UAAU,OACb,OAAO,CAAC,EAAE,KAAK,MAAM,SAAS,MAAM,EACpC,IAAI,SAAU;AAAA,MACb;AAAA,MACA,gBAAgB;AAAA,MAChB,aAAa;AAAA,IACf,GAAG;AAGD,YAAM,UAAU,aAAa,GAAG;AAEhC,aAAO,SAAS,OAAO,KAAK,EAAE,QAAQ,CAAC,CAAC,EACrC,KAAK,MAAM;AACV,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,YACP;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,CAAC,EACA,MAAM,CAAC,QAAQ;AACd,iBAAS;AAAA,UACP,MAAM;AAAA,UACN,SAAS;AAAA,YACP;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH,CAAC;AAAA,IACL,CAAC;AAEH,WAAO,QAAQ,IAAI,OAAO;AAAA,EAC5B;AACF;AASO,SAAS,mBACd,SACA,MACyB;AACzB,SAAO,CAAC,UAAU,aAAa;AAC7B,cAAU,aAAa,OAAO;AAE9B,UAAM,EAAE,SAAS,CAAC,EAAE,IAAI;AAExB,QAAI,YAAY,MAAM;AACpB,YAAM,WAAW,SAAS,EAAE,MAAM,OAAO;AACzC,eAAS,YAAY,EAAE,SAAS,KAAK,CAAC,CAAC;AACvC,YAAM,cAAc,SAAS,EAAE,MAAM,OAAO;AAE5C,kBAAY,UAAU,QAAQ,CAAC,aAAa;AAC1C,cAAM,EAAE,MAAM,KAAK,IAAI;AAGvB,cAAM,kBAAkB,MAAM,aAAa,IAAI;AAC/C,cAAM,eAAe,MAAM,UAAU,IAAI;AACzC,YAAI,CAAC,cAAc;AACjB;AAAA,YACE,gBAAgB;AAAA,cACd,MAAM;AAAA,cACN;AAAA,cACA,OAAO;AAAA,cACP;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF,WAAW,oBAAoB,cAAc;AAC3C;AAAA,YACE,gBAAgB;AAAA,cACd,MAAM;AAAA,cACN;AAAA,cACA,OAAO;AAAA,cACP,eAAe;AAAA,cACf;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,eAAS,aAAa,EAAE,SAAS,KAAK,CAAC,CAAC;AACxC,YAAM,cAAc,SAAS,EAAE,MAAM,OAAO;AAE5C,kBAAY,UAAU,QAAQ,CAAC,aAAa;AAC1C,cAAM,EAAE,MAAM,KAAK,IAAI;AACvB,cAAM,kBAAkB,MAAM,aAAa,IAAI;AAE/C;AAAA,UACE,gBAAgB;AAAA,YACd,MAAM;AAAA,YACN;AAAA,YACA,OAAO;AAAA,YACP;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,CAAC;AAAA,IACH;AAEA,UAAM,WAAW,OAAO,SAAS;AACjC,QAAI,UAAU;AACZ,aAAO,SAAS,gBAAgB,SAAS,MAAM,CAAC,EAAE;AAAA,QAAK,MACrD,QAAQ,QAAQ;AAAA,MAClB;AAAA,IACF,OAAO;AACL,aAAO,QAAQ,QAAQ;AAAA,IACzB;AAAA,EACF;AACF;","names":["pathQuery"]}
|
package/dist/cjs/superglue.cjs
CHANGED
|
@@ -323,7 +323,7 @@ function argsForFetch(getState, pathQuery2, {
|
|
|
323
323
|
return [fetchPath.toString(), { ...options, ...rest }];
|
|
324
324
|
}
|
|
325
325
|
function extractJSON(rsp) {
|
|
326
|
-
return rsp.json().then((json) => {
|
|
326
|
+
return rsp.clone().json().then((json) => {
|
|
327
327
|
return { rsp, json };
|
|
328
328
|
}).catch((e) => {
|
|
329
329
|
e.response = rsp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../lib/index.tsx","../../lib/config.ts","../../lib/utils/url.ts","../../lib/utils/helpers.ts","../../lib/utils/immutability.ts","../../lib/utils/request.ts","../../lib/utils/ujs.ts","../../lib/utils/window.ts","../../lib/actions.ts","../../lib/action_creators/requests.ts","../../lib/action_creators/index.ts","../../lib/components/Navigation.tsx","../../lib/reducers/index.ts","../../lib/hooks/index.ts"],"sourcesContent":["import React, { useRef, useMemo } from 'react'\nimport { config } from './config'\nimport { urlToPageKey, ujsHandlers, argsForHistory } from './utils'\nimport { saveAndProcessPage } from './action_creators'\nimport { historyChange, setCSRFToken } from './actions'\nimport { Provider } from 'react-redux'\n\nimport { createBrowserHistory, createMemoryHistory } from 'history'\n\nimport { NavigationProvider } from './components/Navigation'\nexport { NavigationProvider, NavigationContext } from './components/Navigation'\nexport { saveAndProcessPage } from './action_creators'\nexport {\n beforeFetch,\n beforeVisit,\n beforeRemote,\n updateFragments,\n copyPage,\n removePage,\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n} from './actions'\nexport * from './types'\n\nimport {\n VisitResponse,\n ApplicationProps,\n NavigateTo,\n SuperglueStore,\n SetupProps,\n} from './types'\nexport { superglueReducer, pageReducer, rootReducer } from './reducers'\nexport { getIn } from './utils/immutability'\nexport { urlToPageKey }\nexport * from './hooks'\n\nconst hasWindow = typeof window !== 'undefined'\n\nconst createHistory = () => {\n if (hasWindow) {\n // This is used for client side rendering\n return createBrowserHistory({})\n } else {\n // This is used for server side rendering\n return createMemoryHistory({})\n }\n}\n\nexport const prepareStore = (\n store: SuperglueStore,\n initialPage: VisitResponse,\n path: string\n) => {\n const initialPageKey = urlToPageKey(path)\n const { csrfToken } = initialPage\n\n store.dispatch(\n historyChange({\n pageKey: initialPageKey,\n })\n )\n store.dispatch(saveAndProcessPage(initialPageKey, initialPage))\n store.dispatch(setCSRFToken({ csrfToken }))\n}\n\n/**\n * This is the setup function that the Application calls. Use this function if\n * you like to build your own Application component.\n */\nexport const setup = ({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n navigatorRef,\n}: SetupProps) => {\n config.baseUrl = baseUrl\n\n const { visit, remote } = buildVisitAndRemote(navigatorRef, store)\n\n const initialPageKey = urlToPageKey(path)\n const nextHistory = history || createHistory()\n nextHistory.replace(...argsForHistory(path))\n prepareStore(store, initialPage, path)\n\n const handlers = ujsHandlers({\n visit,\n remote,\n ujsAttributePrefix: 'data-sg',\n store,\n })\n\n return {\n visit,\n remote,\n nextHistory,\n initialPageKey,\n ujs: handlers,\n }\n}\n\n/**\n * The entry point to your superglue application. It sets up the redux Provider,\n * redux state and the Navigation component.\n *\n * This is a simple component, you can override this by copying the source code and\n * use the exported methods used by this component (`start` and `ujsHandler`).\n */\nfunction Application({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n mapping,\n ...rest\n}: ApplicationProps) {\n const navigatorRef = useRef<{ navigateTo: NavigateTo } | null>(null)\n\n const { visit, remote, nextHistory, initialPageKey, ujs } = useMemo(() => {\n return setup({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n navigatorRef,\n })\n }, [])\n\n // The Nav component is pretty bare and can be inherited from for custom\n // behavior or replaced with your own.\n return (\n <div onClick={ujs.onClick} onSubmit={ujs.onSubmit} {...rest}>\n <Provider store={store}>\n <NavigationProvider\n ref={navigatorRef}\n visit={visit}\n remote={remote}\n mapping={mapping}\n history={nextHistory}\n initialPageKey={initialPageKey}\n />\n </Provider>\n </div>\n )\n}\n\nexport { Application }\n","export const config = {\n baseUrl: '',\n maxPages: 20,\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","import { GraftResponse, HistoryState, VisitResponse } from '../types'\nimport { urlToPageKey } from './url'\n\nexport function isGraft(page: GraftResponse | VisitResponse): boolean {\n return 'action' in page && page.action === 'graft'\n}\n\nexport function extractNodeAndPath(page: GraftResponse): {\n node: unknown\n pathToNode: string\n} {\n const { data: node, action, path: pathToNode } = page\n\n if (action === 'graft') {\n return { node, pathToNode }\n } else {\n const errMsg =\n 'Expected page to be a graft response rendered from node filtering.'\n throw new Error(errMsg)\n }\n}\n\nexport function argsForHistory(path: string): [string, HistoryState] {\n const pageKey = urlToPageKey(path)\n\n return [\n path,\n {\n superglue: true,\n pageKey,\n posX: 0,\n posY: 0,\n },\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","import { formatForXHR } from './url'\nimport { config } from '../config'\nimport { BasicRequestInit, ParsedResponse, RootState } from '../types'\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 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","import {\n Handlers,\n UJSHandlers,\n SuperglueStore,\n ApplicationVisit,\n ApplicationRemote,\n RemoteProps,\n VisitProps,\n} from '../types'\n\nexport class HandlerBuilder {\n public attributePrefix: string\n public visit: ApplicationVisit\n public remote: ApplicationRemote\n private store: SuperglueStore\n\n constructor({\n ujsAttributePrefix,\n visit,\n remote,\n store,\n }: {\n ujsAttributePrefix: string\n visit: ApplicationVisit\n remote: ApplicationRemote\n store: SuperglueStore\n }) {\n this.attributePrefix = ujsAttributePrefix\n this.isUJS = this.isUJS.bind(this)\n this.store = store\n\n this.handleSubmit = this.handleSubmit.bind(this)\n this.handleClick = this.handleClick.bind(this)\n\n this.visit = visit\n this.remote = remote\n this.visitOrRemote = this.visitOrRemote.bind(this)\n }\n\n retrieveLink(target: Element): HTMLAnchorElement | undefined {\n const link = target.closest<HTMLAnchorElement>('a')\n if (link && link.href.length !== 0) {\n return link\n }\n }\n\n isNonStandardClick(\n event: React.MouseEvent<HTMLDivElement, MouseEvent>\n ): boolean {\n return (\n event.button > 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n )\n }\n\n isUJS(node: HTMLFormElement | HTMLAnchorElement): boolean {\n const hasVisit = !!node.getAttribute(this.attributePrefix + '-visit')\n const hasRemote = !!node.getAttribute(this.attributePrefix + '-remote')\n\n return hasVisit || hasRemote\n }\n\n handleSubmit(event: React.FormEvent<HTMLDivElement>): void {\n const form = event.target\n\n if (!(form instanceof HTMLFormElement)) {\n return\n }\n\n if (!this.isUJS(form)) {\n return\n }\n\n event.preventDefault()\n\n const url = form.getAttribute('action')\n if (!url) {\n return\n }\n\n const method = (form.getAttribute('method') || 'POST').toUpperCase()\n\n this.visitOrRemote(form, url, {\n method,\n body: new FormData(form),\n })\n }\n\n handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>): void {\n if (!(event.target instanceof Element)) {\n return\n }\n\n const link = this.retrieveLink(event.target)\n const isNonStandard = this.isNonStandardClick(event)\n if (!link || isNonStandard || !this.isUJS(link)) {\n return\n }\n\n event.preventDefault()\n const url = link.getAttribute('href')\n if (!url) {\n return\n }\n\n this.visitOrRemote(link, url, { method: 'GET' })\n }\n\n visitOrRemote(\n linkOrForm: HTMLAnchorElement | HTMLFormElement,\n url: string,\n opts: RemoteProps | VisitProps\n ): void {\n const dataset = { ...linkOrForm.dataset }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-visit')) {\n this.visit(url, { ...opts, dataset })\n }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-remote')) {\n const { currentPageKey } = this.store.getState().superglue\n this.remote(url, {\n ...opts,\n pageKey: currentPageKey,\n dataset,\n })\n }\n }\n\n handlers(): Handlers {\n return {\n onClick: this.handleClick,\n onSubmit: this.handleSubmit,\n }\n }\n}\n\nexport const ujsHandlers: UJSHandlers = ({\n ujsAttributePrefix,\n visit,\n remote,\n store,\n}) => {\n const builder = new HandlerBuilder({\n visit,\n remote,\n ujsAttributePrefix,\n store,\n })\n\n return builder.handlers()\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 VisitResponse,\n JSONMappable,\n Keypath,\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: VisitResponse }) => {\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 called whenever a fragment is received from `visit` or updated\n * using `remote`. Its a useful action to use for cross cutting concerns like a\n * shared header or a shopping cart. For example:\n *\n * ```\n * import { updateFragments } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(updateFragments, (state, action) => {\n * // Update the slice using the latest and greatest.\n * return action.value\n * ```\n */\nexport const updateFragments = createAction<{\n name: string\n path: Keypath\n pageKey: PageKey\n value: JSONMappable\n previousValue?: JSONMappable\n}>('@@superglue/UPDATE_FRAGMENTS')\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","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} from '../actions'\nimport { saveAndProcessPage } from './index'\nimport {\n FetchArgs,\n VisitResponse,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n NavigationAction,\n VisitMeta,\n} from '../types'\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(superglueError({ message: err.message }))\n throw err\n}\n\nfunction buildMeta(\n pageKey: string,\n page: VisitResponse,\n state: SuperglueState,\n rsp: Response,\n fetchArgs: FetchArgs\n): Meta {\n const { assets: prevAssets } = state\n const { assets: nextAssets } = page\n\n return {\n pageKey,\n page,\n redirected: rsp.redirected,\n rsp,\n fetchArgs,\n componentIdentifier: page.componentIdentifier,\n needsRefresh: needsRefresh(prevAssets, nextAssets),\n }\n}\n\nexport class MismatchedComponentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MismatchedComponentError'\n }\n}\n\nexport const remote: RemoteCreator = (\n path,\n {\n pageKey: targetPageKey,\n force = false,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\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 = {} } = 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 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 const page = beforeSave(pages[pageKey], json)\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 = {} } = getState()\n const isGet = fetchArgs[1].method === 'GET'\n const pageKey = calculatePageKey(rsp, isGet, currentPageKey)\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 meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n const visitMeta: VisitMeta = {\n ...meta,\n navigationAction: calculateNavAction(\n meta,\n rsp,\n isGet,\n pageKey,\n currentPageKey,\n revisit\n ),\n }\n\n const page = beforeSave(pages[pageKey], json)\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 isGet: boolean,\n pageKey: string,\n currentPageKey: string,\n revisit: boolean\n) {\n let navigationAction: NavigationAction = 'push'\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 { urlToPageKey, getIn, propsAtParam } from '../utils'\nimport {\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n updateFragments,\n handleGraft,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n VisitResponse,\n SaveAndProcessPageThunk,\n DefermentThunk,\n GraftResponse,\n Defer,\n JSONMappable,\n} from '../types'\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\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: VisitResponse | GraftResponse\n): SaveAndProcessPageThunk {\n return (dispatch, getState) => {\n pageKey = urlToPageKey(pageKey)\n\n const { defers = [] } = page\n\n if ('action' in page) {\n const prevPage = getState().pages[pageKey]\n dispatch(handleGraft({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n // A fragment only works on a block in props_template. So using getIn\n // will always return a JSONMappable\n const currentFragment = getIn(currentPage, path) as JSONMappable\n const prevFragment = getIn(prevPage, path) as JSONMappable\n if (!prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n } else if (currentFragment !== prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n previousValue: prevFragment,\n path,\n })\n )\n }\n })\n } else {\n dispatch(saveResponse({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n const currentFragment = getIn(currentPage, path) as JSONMappable\n\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n })\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, defers)).then(() =>\n Promise.resolve()\n )\n } else {\n return Promise.resolve()\n }\n }\n}\n","import React, {\n createContext,\n useEffect,\n useLayoutEffect,\n forwardRef,\n useImperativeHandle,\n ForwardedRef,\n} from 'react'\nimport { urlToPageKey } from '../utils'\nimport { removePage, setActivePage } from '../actions'\nimport {\n HistoryState,\n RootState,\n NavigateTo,\n NavigationContextProps,\n NavigationProviderProps,\n AllPages,\n SuperglueState,\n} from '../types'\nimport { Update } from 'history'\nimport { useDispatch, useSelector, useStore } from 'react-redux'\n\nconst NavigationContext = createContext<NavigationContextProps>(\n {} as NavigationContextProps\n)\n\nconst hasWindow = typeof window !== 'undefined'\n\nconst setWindowScroll = (posX: number, posY: number): void => {\n hasWindow && window.scrollTo(posX, posY)\n}\n\nconst notFound = (identifier: string | undefined): never => {\n let reminder = ''\n if (!identifier) {\n reminder =\n 'Did you forget to add `json.componentIdentifier` in your application.json.props layout?'\n }\n\n const error = new Error(\n `Superglue Nav component was looking for ${identifier} but could not find it in your mapping. ${reminder}`\n )\n\n throw error\n}\n\nconst NavigationProvider = forwardRef(function NavigationProvider(\n { history, visit, remote, mapping }: NavigationProviderProps,\n ref: ForwardedRef<{ navigateTo: NavigateTo | null }>\n) {\n const dispatch = useDispatch()\n const pages = useSelector<RootState, AllPages>((state) => state.pages)\n const superglue = useSelector<RootState, SuperglueState>(\n (state) => state.superglue\n )\n const currentPageKey = useSelector<RootState, string>(\n (state) => state.superglue.currentPageKey\n )\n const store = useStore()\n\n useEffect(() => {\n return history.listen(onHistoryChange)\n }, [])\n\n useLayoutEffect(() => {\n const state = history.location.state as HistoryState\n if (state && 'superglue' in state) {\n const { posX, posY } = state\n setWindowScroll(posX, posY)\n }\n }, [currentPageKey])\n\n useImperativeHandle(\n ref,\n () => {\n return {\n navigateTo,\n }\n },\n []\n )\n\n const onHistoryChange = ({ location, action }: Update): void => {\n const state = location.state as HistoryState\n\n if (action !== 'POP') {\n return\n }\n\n if (!state && location.hash !== '') {\n const nextPageKey = urlToPageKey(location.pathname + location.search)\n const containsKey = !!pages[nextPageKey]\n if (containsKey) {\n history.replace(\n {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n },\n {\n pageKey: nextPageKey,\n superglue: true,\n posY: window.pageYOffset,\n posX: window.pageXOffset,\n }\n )\n }\n }\n\n if (state && 'superglue' in state) {\n const { pageKey } = state\n const prevPageKey = store.getState().superglue.currentPageKey\n const containsKey = !!pages[pageKey]\n\n if (containsKey) {\n const { restoreStrategy } = pages[pageKey]\n\n switch (restoreStrategy) {\n case 'fromCacheOnly':\n dispatch(setActivePage({ pageKey }))\n break\n case 'fromCacheAndRevisitInBackground':\n dispatch(setActivePage({ pageKey }))\n visit(pageKey, { revisit: true })\n break\n case 'revisitOnly':\n default:\n visit(pageKey, { revisit: true }).then(() => {\n const noNav =\n prevPageKey === store.getState().superglue.currentPageKey\n if (noNav) {\n // When \"POP'ed\", revisiting (using revisit: true) a page can result in\n // a redirect, or a render of the same page.\n //\n // When its a redirect, calculateNavAction will correctly set the\n // navigationAction to `replace` this is the noop scenario.\n //\n // When its the same page, navigationAction is set to `none` and\n // no navigation took place. In that case, we have to set the\n // activePage otherwise the user is stuck on the original page.\n dispatch(setActivePage({ pageKey }))\n }\n })\n }\n } else {\n visit(pageKey, { revisit: true }).then(() => {\n const noNav =\n prevPageKey === store.getState().superglue.currentPageKey\n if (noNav) {\n dispatch(setActivePage({ pageKey }))\n }\n })\n }\n }\n }\n\n const navigateTo: NavigateTo = (\n path,\n { action } = {\n action: 'push',\n }\n ) => {\n if (action === 'none') {\n return false\n }\n\n const nextPageKey = urlToPageKey(path)\n const hasPage = Object.prototype.hasOwnProperty.call(\n store.getState().pages,\n nextPageKey\n )\n\n if (hasPage) {\n const location = history.location\n const state = location.state as HistoryState\n const historyArgs = [\n path,\n {\n pageKey: nextPageKey,\n superglue: true,\n posY: 0,\n posX: 0,\n },\n ] as const\n\n if (action === 'push') {\n if (hasWindow) {\n history.replace(\n {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n },\n {\n ...state,\n posY: window.scrollY,\n posX: window.scrollX,\n }\n )\n }\n\n history.push(...historyArgs)\n dispatch(setActivePage({ pageKey: nextPageKey }))\n }\n\n if (action === 'replace') {\n history.replace(...historyArgs)\n\n if (currentPageKey !== nextPageKey) {\n dispatch(setActivePage({ pageKey: nextPageKey }))\n dispatch(removePage({ pageKey: currentPageKey }))\n }\n }\n return true\n } else {\n console.warn(\n `\\`navigateTo\\` was called , but could not find\n the pageKey in the store. This may happen when the wrong\n content_location was set in your non-get controller action.\n No navigation will take place`\n )\n return false\n }\n }\n\n const { search } = superglue\n const { componentIdentifier } = pages[currentPageKey]\n const Component = mapping[componentIdentifier]\n\n if (Component) {\n return (\n <NavigationContext.Provider\n value={{ pageKey: currentPageKey, search, navigateTo, visit, remote }}\n >\n <Component />\n </NavigationContext.Provider>\n )\n } else {\n notFound(componentIdentifier)\n }\n})\n\nexport { NavigationContext, NavigationProvider }\n","import { setIn, getIn, urlToPageKey, parsePageKey } from '../utils'\nimport type { Action } from '@reduxjs/toolkit'\nimport {\n saveResponse,\n handleGraft,\n historyChange,\n copyPage,\n setCSRFToken,\n setActivePage,\n removePage,\n} from '../actions'\nimport { config } from '../config'\nimport {\n AllPages,\n Page,\n VisitResponse,\n Fragment,\n GraftResponse,\n SuperglueState,\n JSONMappable,\n} from '../types'\n\nfunction addPlaceholdersToDeferredNodes(existingPage: Page, page: Page): Page {\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\nfunction constrainPagesSize(state: AllPages) {\n const { maxPages } = config\n const allPageKeys = Object.keys(state)\n const cacheTimesRecentFirst = allPageKeys\n .map((key) => state[key].savedAt)\n .sort((a, b) => b - a)\n\n for (const key of Array.from(allPageKeys)) {\n if (state[key].savedAt <= cacheTimesRecentFirst[maxPages - 1]) {\n delete state[key]\n }\n }\n}\n\nfunction handleSaveResponse(\n state: AllPages,\n pageKey: string,\n page: VisitResponse\n): AllPages {\n state = { ...state }\n\n let nextPage: Page = {\n ...page,\n savedAt: Date.now(),\n }\n\n const existingPage = state[pageKey]\n\n if (existingPage) {\n nextPage = addPlaceholdersToDeferredNodes(existingPage, nextPage)\n }\n constrainPagesSize(state)\n state[pageKey] = nextPage\n\n return state\n}\n\nexport function appendReceivedFragmentsOntoPage(\n state: AllPages,\n pageKey: string,\n receivedFragments: Fragment[]\n): AllPages {\n if (!pageKey) {\n return state\n }\n\n if (receivedFragments.length === 0) {\n return state\n }\n\n const currentPage = state[pageKey]\n const { fragments: prevFragments = [] } = currentPage\n const nextFragments = [...prevFragments]\n const existingKeys: Record<string, boolean> = {}\n prevFragments.forEach((frag) => (existingKeys[frag.path] = true))\n\n receivedFragments.forEach((frag) => {\n if (!existingKeys[frag.path]) {\n nextFragments.push(frag)\n }\n })\n\n const nextPage = {\n ...currentPage,\n fragments: nextFragments,\n }\n\n const nextState = { ...state }\n nextState[pageKey] = nextPage\n\n return nextState\n}\n\nexport function graftNodeOntoPage(\n state: AllPages,\n pageKey: string,\n node: JSONMappable,\n pathToNode: string\n): AllPages {\n if (!node) {\n console.warn(\n 'There was no node returned in the response. Do you have the correct key path in your props_at?'\n )\n return state\n }\n\n if (!pathToNode || !pageKey) {\n return state\n }\n const fullPathToNode = [pageKey, pathToNode].join('.')\n return setIn(state, fullPathToNode, node)\n}\n\nfunction handleGraftResponse(\n state: AllPages,\n pageKey: string,\n page: GraftResponse\n): AllPages {\n const currentPage = state[pageKey]\n if (!currentPage) {\n const error = new Error(\n `Superglue was looking for ${pageKey} in your state, but could not find it in your mapping. Did you forget to pass in a valid pageKey to this.props.remote or this.props.visit?`\n )\n throw error\n }\n const {\n data: receivedNode,\n path: pathToNode,\n fragments: receivedFragments = [],\n } = page\n\n return [\n (nextState: AllPages) =>\n graftNodeOntoPage(nextState, pageKey, receivedNode, pathToNode),\n (nextState: AllPages) =>\n appendReceivedFragmentsOntoPage(nextState, pageKey, receivedFragments),\n ].reduce((memo, fn) => fn(memo), state)\n}\n\nexport function pageReducer(state: AllPages = {}, action: Action): AllPages {\n if (removePage.match(action)) {\n const { pageKey } = action.payload\n const nextState = { ...state }\n delete nextState[pageKey]\n\n return nextState\n }\n\n if (copyPage.match(action)) {\n const nextState = { ...state }\n const { from, to } = action.payload\n\n nextState[urlToPageKey(to)] = JSON.parse(JSON.stringify(nextState[from]))\n\n return nextState\n }\n\n if (handleGraft.match(action)) {\n const { pageKey, page } = action.payload\n\n return handleGraftResponse(state, pageKey, page)\n }\n\n if (saveResponse.match(action)) {\n const { pageKey, page } = action.payload\n const nextState = handleSaveResponse(state, pageKey, page)\n return nextState\n }\n\n return state\n}\n\nexport function superglueReducer(\n state: SuperglueState = {\n currentPageKey: '',\n search: {},\n assets: [],\n },\n action: Action\n): SuperglueState {\n if (setCSRFToken.match(action)) {\n const { csrfToken } = action.payload\n return { ...state, csrfToken: csrfToken }\n }\n\n if (setActivePage.match(action)) {\n const { pageKey } = action.payload\n const { search } = parsePageKey(pageKey)\n\n return {\n ...state,\n search,\n currentPageKey: pageKey,\n }\n }\n\n if (historyChange.match(action)) {\n const { pageKey } = action.payload\n const { search } = parsePageKey(pageKey)\n\n return {\n ...state,\n currentPageKey: pageKey,\n search,\n }\n }\n\n if (saveResponse.match(action)) {\n const {\n page: { csrfToken, assets },\n } = action.payload\n\n return { ...state, csrfToken, assets }\n }\n\n return state\n}\n\nexport const rootReducer = {\n superglue: superglueReducer,\n pages: pageReducer,\n}\n","import { useSelector } from 'react-redux'\nimport { JSONMappable, Page, RootState, SuperglueState } from '../types'\n\n/**\n * A lightweight hook that grabs the superglue state from the store.\n */\nexport function useSuperglue() {\n return useSelector<RootState, SuperglueState>((state) => state.superglue)\n}\n\n/**\n * A lightweight hook that grabs the current page's content from the store.\n */\nexport function useContent<T = JSONMappable>() {\n const superglueState = useSuperglue()\n const currentPageKey = superglueState.currentPageKey\n\n return useSelector<RootState<T>, Page<T>>(\n (state) => state.pages[currentPageKey]\n ).data\n}\n"],"mappings":"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","names":["import_react","pathQuery","remote","import_react_redux","NavigationProvider","remote","React","import_react_redux","hasWindow","remote","React"]}
|
|
1
|
+
{"version":3,"sources":["../../lib/index.tsx","../../lib/config.ts","../../lib/utils/url.ts","../../lib/utils/helpers.ts","../../lib/utils/immutability.ts","../../lib/utils/request.ts","../../lib/utils/ujs.ts","../../lib/utils/window.ts","../../lib/actions.ts","../../lib/action_creators/requests.ts","../../lib/action_creators/index.ts","../../lib/components/Navigation.tsx","../../lib/reducers/index.ts","../../lib/hooks/index.ts"],"sourcesContent":["import React, { useRef, useMemo } from 'react'\nimport { config } from './config'\nimport { urlToPageKey, ujsHandlers, argsForHistory } from './utils'\nimport { saveAndProcessPage } from './action_creators'\nimport { historyChange, setCSRFToken } from './actions'\nimport { Provider } from 'react-redux'\n\nimport { createBrowserHistory, createMemoryHistory } from 'history'\n\nimport { NavigationProvider } from './components/Navigation'\nexport { NavigationProvider, NavigationContext } from './components/Navigation'\nexport { saveAndProcessPage } from './action_creators'\nexport {\n beforeFetch,\n beforeVisit,\n beforeRemote,\n updateFragments,\n copyPage,\n removePage,\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n} from './actions'\nexport * from './types'\n\nimport {\n VisitResponse,\n ApplicationProps,\n NavigateTo,\n SuperglueStore,\n SetupProps,\n} from './types'\nexport { superglueReducer, pageReducer, rootReducer } from './reducers'\nexport { getIn } from './utils/immutability'\nexport { urlToPageKey }\nexport * from './hooks'\n\nconst hasWindow = typeof window !== 'undefined'\n\nconst createHistory = () => {\n if (hasWindow) {\n // This is used for client side rendering\n return createBrowserHistory({})\n } else {\n // This is used for server side rendering\n return createMemoryHistory({})\n }\n}\n\nexport const prepareStore = (\n store: SuperglueStore,\n initialPage: VisitResponse,\n path: string\n) => {\n const initialPageKey = urlToPageKey(path)\n const { csrfToken } = initialPage\n\n store.dispatch(\n historyChange({\n pageKey: initialPageKey,\n })\n )\n store.dispatch(saveAndProcessPage(initialPageKey, initialPage))\n store.dispatch(setCSRFToken({ csrfToken }))\n}\n\n/**\n * This is the setup function that the Application calls. Use this function if\n * you like to build your own Application component.\n */\nexport const setup = ({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n navigatorRef,\n}: SetupProps) => {\n config.baseUrl = baseUrl\n\n const { visit, remote } = buildVisitAndRemote(navigatorRef, store)\n\n const initialPageKey = urlToPageKey(path)\n const nextHistory = history || createHistory()\n nextHistory.replace(...argsForHistory(path))\n prepareStore(store, initialPage, path)\n\n const handlers = ujsHandlers({\n visit,\n remote,\n ujsAttributePrefix: 'data-sg',\n store,\n })\n\n return {\n visit,\n remote,\n nextHistory,\n initialPageKey,\n ujs: handlers,\n }\n}\n\n/**\n * The entry point to your superglue application. It sets up the redux Provider,\n * redux state and the Navigation component.\n *\n * This is a simple component, you can override this by copying the source code and\n * use the exported methods used by this component (`start` and `ujsHandler`).\n */\nfunction Application({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n mapping,\n ...rest\n}: ApplicationProps) {\n const navigatorRef = useRef<{ navigateTo: NavigateTo } | null>(null)\n\n const { visit, remote, nextHistory, initialPageKey, ujs } = useMemo(() => {\n return setup({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n navigatorRef,\n })\n }, [])\n\n // The Nav component is pretty bare and can be inherited from for custom\n // behavior or replaced with your own.\n return (\n <div onClick={ujs.onClick} onSubmit={ujs.onSubmit} {...rest}>\n <Provider store={store}>\n <NavigationProvider\n ref={navigatorRef}\n visit={visit}\n remote={remote}\n mapping={mapping}\n history={nextHistory}\n initialPageKey={initialPageKey}\n />\n </Provider>\n </div>\n )\n}\n\nexport { Application }\n","export const config = {\n baseUrl: '',\n maxPages: 20,\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","import { GraftResponse, HistoryState, VisitResponse } from '../types'\nimport { urlToPageKey } from './url'\n\nexport function isGraft(page: GraftResponse | VisitResponse): boolean {\n return 'action' in page && page.action === 'graft'\n}\n\nexport function extractNodeAndPath(page: GraftResponse): {\n node: unknown\n pathToNode: string\n} {\n const { data: node, action, path: pathToNode } = page\n\n if (action === 'graft') {\n return { node, pathToNode }\n } else {\n const errMsg =\n 'Expected page to be a graft response rendered from node filtering.'\n throw new Error(errMsg)\n }\n}\n\nexport function argsForHistory(path: string): [string, HistoryState] {\n const pageKey = urlToPageKey(path)\n\n return [\n path,\n {\n superglue: true,\n pageKey,\n posX: 0,\n posY: 0,\n },\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","import { formatForXHR } from './url'\nimport { config } from '../config'\nimport { BasicRequestInit, ParsedResponse, RootState } from '../types'\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 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 .clone()\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","import {\n Handlers,\n UJSHandlers,\n SuperglueStore,\n ApplicationVisit,\n ApplicationRemote,\n RemoteProps,\n VisitProps,\n} from '../types'\n\nexport class HandlerBuilder {\n public attributePrefix: string\n public visit: ApplicationVisit\n public remote: ApplicationRemote\n private store: SuperglueStore\n\n constructor({\n ujsAttributePrefix,\n visit,\n remote,\n store,\n }: {\n ujsAttributePrefix: string\n visit: ApplicationVisit\n remote: ApplicationRemote\n store: SuperglueStore\n }) {\n this.attributePrefix = ujsAttributePrefix\n this.isUJS = this.isUJS.bind(this)\n this.store = store\n\n this.handleSubmit = this.handleSubmit.bind(this)\n this.handleClick = this.handleClick.bind(this)\n\n this.visit = visit\n this.remote = remote\n this.visitOrRemote = this.visitOrRemote.bind(this)\n }\n\n retrieveLink(target: Element): HTMLAnchorElement | undefined {\n const link = target.closest<HTMLAnchorElement>('a')\n if (link && link.href.length !== 0) {\n return link\n }\n }\n\n isNonStandardClick(\n event: React.MouseEvent<HTMLDivElement, MouseEvent>\n ): boolean {\n return (\n event.button > 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n )\n }\n\n isUJS(node: HTMLFormElement | HTMLAnchorElement): boolean {\n const hasVisit = !!node.getAttribute(this.attributePrefix + '-visit')\n const hasRemote = !!node.getAttribute(this.attributePrefix + '-remote')\n\n return hasVisit || hasRemote\n }\n\n handleSubmit(event: React.FormEvent<HTMLDivElement>): void {\n const form = event.target\n\n if (!(form instanceof HTMLFormElement)) {\n return\n }\n\n if (!this.isUJS(form)) {\n return\n }\n\n event.preventDefault()\n\n const url = form.getAttribute('action')\n if (!url) {\n return\n }\n\n const method = (form.getAttribute('method') || 'POST').toUpperCase()\n\n this.visitOrRemote(form, url, {\n method,\n body: new FormData(form),\n })\n }\n\n handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>): void {\n if (!(event.target instanceof Element)) {\n return\n }\n\n const link = this.retrieveLink(event.target)\n const isNonStandard = this.isNonStandardClick(event)\n if (!link || isNonStandard || !this.isUJS(link)) {\n return\n }\n\n event.preventDefault()\n const url = link.getAttribute('href')\n if (!url) {\n return\n }\n\n this.visitOrRemote(link, url, { method: 'GET' })\n }\n\n visitOrRemote(\n linkOrForm: HTMLAnchorElement | HTMLFormElement,\n url: string,\n opts: RemoteProps | VisitProps\n ): void {\n const dataset = { ...linkOrForm.dataset }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-visit')) {\n this.visit(url, { ...opts, dataset })\n }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-remote')) {\n const { currentPageKey } = this.store.getState().superglue\n this.remote(url, {\n ...opts,\n pageKey: currentPageKey,\n dataset,\n })\n }\n }\n\n handlers(): Handlers {\n return {\n onClick: this.handleClick,\n onSubmit: this.handleSubmit,\n }\n }\n}\n\nexport const ujsHandlers: UJSHandlers = ({\n ujsAttributePrefix,\n visit,\n remote,\n store,\n}) => {\n const builder = new HandlerBuilder({\n visit,\n remote,\n ujsAttributePrefix,\n store,\n })\n\n return builder.handlers()\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 VisitResponse,\n JSONMappable,\n Keypath,\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: VisitResponse }) => {\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 called whenever a fragment is received from `visit` or updated\n * using `remote`. Its a useful action to use for cross cutting concerns like a\n * shared header or a shopping cart. For example:\n *\n * ```\n * import { updateFragments } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(updateFragments, (state, action) => {\n * // Update the slice using the latest and greatest.\n * return action.value\n * ```\n */\nexport const updateFragments = createAction<{\n name: string\n path: Keypath\n pageKey: PageKey\n value: JSONMappable\n previousValue?: JSONMappable\n}>('@@superglue/UPDATE_FRAGMENTS')\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","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} from '../actions'\nimport { saveAndProcessPage } from './index'\nimport {\n FetchArgs,\n VisitResponse,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n NavigationAction,\n VisitMeta,\n} from '../types'\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(superglueError({ message: err.message }))\n throw err\n}\n\nfunction buildMeta(\n pageKey: string,\n page: VisitResponse,\n state: SuperglueState,\n rsp: Response,\n fetchArgs: FetchArgs\n): Meta {\n const { assets: prevAssets } = state\n const { assets: nextAssets } = page\n\n return {\n pageKey,\n page,\n redirected: rsp.redirected,\n rsp,\n fetchArgs,\n componentIdentifier: page.componentIdentifier,\n needsRefresh: needsRefresh(prevAssets, nextAssets),\n }\n}\n\nexport class MismatchedComponentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MismatchedComponentError'\n }\n}\n\nexport const remote: RemoteCreator = (\n path,\n {\n pageKey: targetPageKey,\n force = false,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\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 = {} } = 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 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 const page = beforeSave(pages[pageKey], json)\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 = {} } = getState()\n const isGet = fetchArgs[1].method === 'GET'\n const pageKey = calculatePageKey(rsp, isGet, currentPageKey)\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 meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n const visitMeta: VisitMeta = {\n ...meta,\n navigationAction: calculateNavAction(\n meta,\n rsp,\n isGet,\n pageKey,\n currentPageKey,\n revisit\n ),\n }\n\n const page = beforeSave(pages[pageKey], json)\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 isGet: boolean,\n pageKey: string,\n currentPageKey: string,\n revisit: boolean\n) {\n let navigationAction: NavigationAction = 'push'\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 { urlToPageKey, getIn, propsAtParam } from '../utils'\nimport {\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n updateFragments,\n handleGraft,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n VisitResponse,\n SaveAndProcessPageThunk,\n DefermentThunk,\n GraftResponse,\n Defer,\n JSONMappable,\n} from '../types'\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\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: VisitResponse | GraftResponse\n): SaveAndProcessPageThunk {\n return (dispatch, getState) => {\n pageKey = urlToPageKey(pageKey)\n\n const { defers = [] } = page\n\n if ('action' in page) {\n const prevPage = getState().pages[pageKey]\n dispatch(handleGraft({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n // A fragment only works on a block in props_template. So using getIn\n // will always return a JSONMappable\n const currentFragment = getIn(currentPage, path) as JSONMappable\n const prevFragment = getIn(prevPage, path) as JSONMappable\n if (!prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n } else if (currentFragment !== prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n previousValue: prevFragment,\n path,\n })\n )\n }\n })\n } else {\n dispatch(saveResponse({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n const currentFragment = getIn(currentPage, path) as JSONMappable\n\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n })\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, defers)).then(() =>\n Promise.resolve()\n )\n } else {\n return Promise.resolve()\n }\n }\n}\n","import React, {\n createContext,\n useEffect,\n useLayoutEffect,\n forwardRef,\n useImperativeHandle,\n ForwardedRef,\n} from 'react'\nimport { urlToPageKey } from '../utils'\nimport { removePage, setActivePage } from '../actions'\nimport {\n HistoryState,\n RootState,\n NavigateTo,\n NavigationContextProps,\n NavigationProviderProps,\n AllPages,\n SuperglueState,\n} from '../types'\nimport { Update } from 'history'\nimport { useDispatch, useSelector, useStore } from 'react-redux'\n\nconst NavigationContext = createContext<NavigationContextProps>(\n {} as NavigationContextProps\n)\n\nconst hasWindow = typeof window !== 'undefined'\n\nconst setWindowScroll = (posX: number, posY: number): void => {\n hasWindow && window.scrollTo(posX, posY)\n}\n\nconst notFound = (identifier: string | undefined): never => {\n let reminder = ''\n if (!identifier) {\n reminder =\n 'Did you forget to add `json.componentIdentifier` in your application.json.props layout?'\n }\n\n const error = new Error(\n `Superglue Nav component was looking for ${identifier} but could not find it in your mapping. ${reminder}`\n )\n\n throw error\n}\n\nconst NavigationProvider = forwardRef(function NavigationProvider(\n { history, visit, remote, mapping }: NavigationProviderProps,\n ref: ForwardedRef<{ navigateTo: NavigateTo | null }>\n) {\n const dispatch = useDispatch()\n const pages = useSelector<RootState, AllPages>((state) => state.pages)\n const superglue = useSelector<RootState, SuperglueState>(\n (state) => state.superglue\n )\n const currentPageKey = useSelector<RootState, string>(\n (state) => state.superglue.currentPageKey\n )\n const store = useStore<RootState>()\n\n useEffect(() => {\n return history.listen(onHistoryChange)\n }, [])\n\n useLayoutEffect(() => {\n const state = history.location.state as HistoryState\n if (state && 'superglue' in state) {\n const { posX, posY } = state\n setWindowScroll(posX, posY)\n }\n }, [currentPageKey])\n\n useImperativeHandle(\n ref,\n () => {\n return {\n navigateTo,\n }\n },\n []\n )\n\n const onHistoryChange = ({ location, action }: Update): void => {\n const state = location.state as HistoryState\n\n if (action !== 'POP') {\n return\n }\n\n if (!state && location.hash !== '') {\n const nextPageKey = urlToPageKey(location.pathname + location.search)\n const containsKey = !!pages[nextPageKey]\n if (containsKey) {\n history.replace(\n {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n },\n {\n pageKey: nextPageKey,\n superglue: true,\n posY: window.pageYOffset,\n posX: window.pageXOffset,\n }\n )\n }\n }\n\n if (state && 'superglue' in state) {\n const { pageKey } = state\n const prevPageKey = store.getState().superglue.currentPageKey\n const containsKey = !!pages[pageKey]\n\n if (containsKey) {\n const { restoreStrategy } = pages[pageKey]\n\n switch (restoreStrategy) {\n case 'fromCacheOnly':\n dispatch(setActivePage({ pageKey }))\n break\n case 'fromCacheAndRevisitInBackground':\n dispatch(setActivePage({ pageKey }))\n visit(pageKey, { revisit: true })\n break\n case 'revisitOnly':\n default:\n visit(pageKey, { revisit: true }).then(() => {\n const noNav =\n prevPageKey === store.getState().superglue.currentPageKey\n if (noNav) {\n // When \"POP'ed\", revisiting (using revisit: true) a page can result in\n // a redirect, or a render of the same page.\n //\n // When its a redirect, calculateNavAction will correctly set the\n // navigationAction to `replace` this is the noop scenario.\n //\n // When its the same page, navigationAction is set to `none` and\n // no navigation took place. In that case, we have to set the\n // activePage otherwise the user is stuck on the original page.\n dispatch(setActivePage({ pageKey }))\n }\n })\n }\n } else {\n visit(pageKey, { revisit: true }).then(() => {\n const noNav =\n prevPageKey === store.getState().superglue.currentPageKey\n if (noNav) {\n dispatch(setActivePage({ pageKey }))\n }\n })\n }\n }\n }\n\n const navigateTo: NavigateTo = (\n path,\n { action } = {\n action: 'push',\n }\n ) => {\n if (action === 'none') {\n return false\n }\n\n const nextPageKey = urlToPageKey(path)\n const hasPage = Object.prototype.hasOwnProperty.call(\n store.getState().pages,\n nextPageKey\n )\n\n if (hasPage) {\n const location = history.location\n const state = location.state as HistoryState\n const historyArgs = [\n path,\n {\n pageKey: nextPageKey,\n superglue: true,\n posY: 0,\n posX: 0,\n },\n ] as const\n\n if (action === 'push') {\n if (hasWindow) {\n history.replace(\n {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n },\n {\n ...state,\n posY: window.scrollY,\n posX: window.scrollX,\n }\n )\n }\n\n history.push(...historyArgs)\n dispatch(setActivePage({ pageKey: nextPageKey }))\n }\n\n if (action === 'replace') {\n history.replace(...historyArgs)\n\n if (currentPageKey !== nextPageKey) {\n dispatch(setActivePage({ pageKey: nextPageKey }))\n dispatch(removePage({ pageKey: currentPageKey }))\n }\n }\n return true\n } else {\n console.warn(\n `\\`navigateTo\\` was called , but could not find\n the pageKey in the store. This may happen when the wrong\n content_location was set in your non-get controller action.\n No navigation will take place`\n )\n return false\n }\n }\n\n const { search } = superglue\n const { componentIdentifier } = pages[currentPageKey]\n const Component = mapping[componentIdentifier]\n\n if (Component) {\n return (\n <NavigationContext.Provider\n value={{ pageKey: currentPageKey, search, navigateTo, visit, remote }}\n >\n <Component />\n </NavigationContext.Provider>\n )\n } else {\n notFound(componentIdentifier)\n }\n})\n\nexport { NavigationContext, NavigationProvider }\n","import { setIn, getIn, urlToPageKey, parsePageKey } from '../utils'\nimport type { Action } from '@reduxjs/toolkit'\nimport {\n saveResponse,\n handleGraft,\n historyChange,\n copyPage,\n setCSRFToken,\n setActivePage,\n removePage,\n} from '../actions'\nimport { config } from '../config'\nimport {\n AllPages,\n Page,\n VisitResponse,\n Fragment,\n GraftResponse,\n SuperglueState,\n JSONMappable,\n} from '../types'\n\nfunction addPlaceholdersToDeferredNodes(existingPage: Page, page: Page): Page {\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\nfunction constrainPagesSize(state: AllPages) {\n const { maxPages } = config\n const allPageKeys = Object.keys(state)\n const cacheTimesRecentFirst = allPageKeys\n .map((key) => state[key].savedAt)\n .sort((a, b) => b - a)\n\n for (const key of Array.from(allPageKeys)) {\n if (state[key].savedAt <= cacheTimesRecentFirst[maxPages - 1]) {\n delete state[key]\n }\n }\n}\n\nfunction handleSaveResponse(\n state: AllPages,\n pageKey: string,\n page: VisitResponse\n): AllPages {\n state = { ...state }\n\n let nextPage: Page = {\n ...page,\n savedAt: Date.now(),\n }\n\n const existingPage = state[pageKey]\n\n if (existingPage) {\n nextPage = addPlaceholdersToDeferredNodes(existingPage, nextPage)\n }\n constrainPagesSize(state)\n state[pageKey] = nextPage\n\n return state\n}\n\nexport function appendReceivedFragmentsOntoPage(\n state: AllPages,\n pageKey: string,\n receivedFragments: Fragment[]\n): AllPages {\n if (!pageKey) {\n return state\n }\n\n if (receivedFragments.length === 0) {\n return state\n }\n\n const currentPage = state[pageKey]\n const { fragments: prevFragments = [] } = currentPage\n const nextFragments = [...prevFragments]\n const existingKeys: Record<string, boolean> = {}\n prevFragments.forEach((frag) => (existingKeys[frag.path] = true))\n\n receivedFragments.forEach((frag) => {\n if (!existingKeys[frag.path]) {\n nextFragments.push(frag)\n }\n })\n\n const nextPage = {\n ...currentPage,\n fragments: nextFragments,\n }\n\n const nextState = { ...state }\n nextState[pageKey] = nextPage\n\n return nextState\n}\n\nexport function graftNodeOntoPage(\n state: AllPages,\n pageKey: string,\n node: JSONMappable,\n pathToNode: string\n): AllPages {\n if (!node) {\n console.warn(\n 'There was no node returned in the response. Do you have the correct key path in your props_at?'\n )\n return state\n }\n\n if (!pathToNode || !pageKey) {\n return state\n }\n const fullPathToNode = [pageKey, pathToNode].join('.')\n return setIn(state, fullPathToNode, node)\n}\n\nfunction handleGraftResponse(\n state: AllPages,\n pageKey: string,\n page: GraftResponse\n): AllPages {\n const currentPage = state[pageKey]\n if (!currentPage) {\n const error = new Error(\n `Superglue was looking for ${pageKey} in your state, but could not find it in your mapping. Did you forget to pass in a valid pageKey to this.props.remote or this.props.visit?`\n )\n throw error\n }\n const {\n data: receivedNode,\n path: pathToNode,\n fragments: receivedFragments = [],\n } = page\n\n return [\n (nextState: AllPages) =>\n graftNodeOntoPage(nextState, pageKey, receivedNode, pathToNode),\n (nextState: AllPages) =>\n appendReceivedFragmentsOntoPage(nextState, pageKey, receivedFragments),\n ].reduce((memo, fn) => fn(memo), state)\n}\n\nexport function pageReducer(state: AllPages = {}, action: Action): AllPages {\n if (removePage.match(action)) {\n const { pageKey } = action.payload\n const nextState = { ...state }\n delete nextState[pageKey]\n\n return nextState\n }\n\n if (copyPage.match(action)) {\n const nextState = { ...state }\n const { from, to } = action.payload\n\n nextState[urlToPageKey(to)] = JSON.parse(JSON.stringify(nextState[from]))\n\n return nextState\n }\n\n if (handleGraft.match(action)) {\n const { pageKey, page } = action.payload\n\n return handleGraftResponse(state, pageKey, page)\n }\n\n if (saveResponse.match(action)) {\n const { pageKey, page } = action.payload\n const nextState = handleSaveResponse(state, pageKey, page)\n return nextState\n }\n\n return state\n}\n\nexport function superglueReducer(\n state: SuperglueState = {\n currentPageKey: '',\n search: {},\n assets: [],\n },\n action: Action\n): SuperglueState {\n if (setCSRFToken.match(action)) {\n const { csrfToken } = action.payload\n return { ...state, csrfToken: csrfToken }\n }\n\n if (setActivePage.match(action)) {\n const { pageKey } = action.payload\n const { search } = parsePageKey(pageKey)\n\n return {\n ...state,\n search,\n currentPageKey: pageKey,\n }\n }\n\n if (historyChange.match(action)) {\n const { pageKey } = action.payload\n const { search } = parsePageKey(pageKey)\n\n return {\n ...state,\n currentPageKey: pageKey,\n search,\n }\n }\n\n if (saveResponse.match(action)) {\n const {\n page: { csrfToken, assets },\n } = action.payload\n\n return { ...state, csrfToken, assets }\n }\n\n return state\n}\n\nexport const rootReducer = {\n superglue: superglueReducer,\n pages: pageReducer,\n}\n","import { useSelector } from 'react-redux'\nimport { JSONMappable, Page, RootState, SuperglueState } from '../types'\n\n/**\n * A lightweight hook that grabs the superglue state from the store.\n */\nexport function useSuperglue() {\n return useSelector<RootState, SuperglueState>((state) => state.superglue)\n}\n\n/**\n * A lightweight hook that grabs the current page's content from the store.\n */\nexport function useContent<T = JSONMappable>() {\n const superglueState = useSuperglue()\n const currentPageKey = superglueState.currentPageKey\n\n return useSelector<RootState<T>, Page<T>>(\n (state) => state.pages[currentPageKey]\n ).data\n}\n"],"mappings":"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","names":["import_react","pathQuery","remote","import_react_redux","NavigationProvider","remote","React","import_react_redux","hasWindow","remote","React"]}
|
package/dist/superglue.mjs
CHANGED
package/dist/superglue.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/index.tsx","../lib/components/Navigation.tsx","../lib/reducers/index.ts","../lib/hooks/index.ts"],"sourcesContent":["import React, { useRef, useMemo } from 'react'\nimport { config } from './config'\nimport { urlToPageKey, ujsHandlers, argsForHistory } from './utils'\nimport { saveAndProcessPage } from './action_creators'\nimport { historyChange, setCSRFToken } from './actions'\nimport { Provider } from 'react-redux'\n\nimport { createBrowserHistory, createMemoryHistory } from 'history'\n\nimport { NavigationProvider } from './components/Navigation'\nexport { NavigationProvider, NavigationContext } from './components/Navigation'\nexport { saveAndProcessPage } from './action_creators'\nexport {\n beforeFetch,\n beforeVisit,\n beforeRemote,\n updateFragments,\n copyPage,\n removePage,\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n} from './actions'\nexport * from './types'\n\nimport {\n VisitResponse,\n ApplicationProps,\n NavigateTo,\n SuperglueStore,\n SetupProps,\n} from './types'\nexport { superglueReducer, pageReducer, rootReducer } from './reducers'\nexport { getIn } from './utils/immutability'\nexport { urlToPageKey }\nexport * from './hooks'\n\nconst hasWindow = typeof window !== 'undefined'\n\nconst createHistory = () => {\n if (hasWindow) {\n // This is used for client side rendering\n return createBrowserHistory({})\n } else {\n // This is used for server side rendering\n return createMemoryHistory({})\n }\n}\n\nexport const prepareStore = (\n store: SuperglueStore,\n initialPage: VisitResponse,\n path: string\n) => {\n const initialPageKey = urlToPageKey(path)\n const { csrfToken } = initialPage\n\n store.dispatch(\n historyChange({\n pageKey: initialPageKey,\n })\n )\n store.dispatch(saveAndProcessPage(initialPageKey, initialPage))\n store.dispatch(setCSRFToken({ csrfToken }))\n}\n\n/**\n * This is the setup function that the Application calls. Use this function if\n * you like to build your own Application component.\n */\nexport const setup = ({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n navigatorRef,\n}: SetupProps) => {\n config.baseUrl = baseUrl\n\n const { visit, remote } = buildVisitAndRemote(navigatorRef, store)\n\n const initialPageKey = urlToPageKey(path)\n const nextHistory = history || createHistory()\n nextHistory.replace(...argsForHistory(path))\n prepareStore(store, initialPage, path)\n\n const handlers = ujsHandlers({\n visit,\n remote,\n ujsAttributePrefix: 'data-sg',\n store,\n })\n\n return {\n visit,\n remote,\n nextHistory,\n initialPageKey,\n ujs: handlers,\n }\n}\n\n/**\n * The entry point to your superglue application. It sets up the redux Provider,\n * redux state and the Navigation component.\n *\n * This is a simple component, you can override this by copying the source code and\n * use the exported methods used by this component (`start` and `ujsHandler`).\n */\nfunction Application({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n mapping,\n ...rest\n}: ApplicationProps) {\n const navigatorRef = useRef<{ navigateTo: NavigateTo } | null>(null)\n\n const { visit, remote, nextHistory, initialPageKey, ujs } = useMemo(() => {\n return setup({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n navigatorRef,\n })\n }, [])\n\n // The Nav component is pretty bare and can be inherited from for custom\n // behavior or replaced with your own.\n return (\n <div onClick={ujs.onClick} onSubmit={ujs.onSubmit} {...rest}>\n <Provider store={store}>\n <NavigationProvider\n ref={navigatorRef}\n visit={visit}\n remote={remote}\n mapping={mapping}\n history={nextHistory}\n initialPageKey={initialPageKey}\n />\n </Provider>\n </div>\n )\n}\n\nexport { Application }\n","import React, {\n createContext,\n useEffect,\n useLayoutEffect,\n forwardRef,\n useImperativeHandle,\n ForwardedRef,\n} from 'react'\nimport { urlToPageKey } from '../utils'\nimport { removePage, setActivePage } from '../actions'\nimport {\n HistoryState,\n RootState,\n NavigateTo,\n NavigationContextProps,\n NavigationProviderProps,\n AllPages,\n SuperglueState,\n} from '../types'\nimport { Update } from 'history'\nimport { useDispatch, useSelector, useStore } from 'react-redux'\n\nconst NavigationContext = createContext<NavigationContextProps>(\n {} as NavigationContextProps\n)\n\nconst hasWindow = typeof window !== 'undefined'\n\nconst setWindowScroll = (posX: number, posY: number): void => {\n hasWindow && window.scrollTo(posX, posY)\n}\n\nconst notFound = (identifier: string | undefined): never => {\n let reminder = ''\n if (!identifier) {\n reminder =\n 'Did you forget to add `json.componentIdentifier` in your application.json.props layout?'\n }\n\n const error = new Error(\n `Superglue Nav component was looking for ${identifier} but could not find it in your mapping. ${reminder}`\n )\n\n throw error\n}\n\nconst NavigationProvider = forwardRef(function NavigationProvider(\n { history, visit, remote, mapping }: NavigationProviderProps,\n ref: ForwardedRef<{ navigateTo: NavigateTo | null }>\n) {\n const dispatch = useDispatch()\n const pages = useSelector<RootState, AllPages>((state) => state.pages)\n const superglue = useSelector<RootState, SuperglueState>(\n (state) => state.superglue\n )\n const currentPageKey = useSelector<RootState, string>(\n (state) => state.superglue.currentPageKey\n )\n const store = useStore()\n\n useEffect(() => {\n return history.listen(onHistoryChange)\n }, [])\n\n useLayoutEffect(() => {\n const state = history.location.state as HistoryState\n if (state && 'superglue' in state) {\n const { posX, posY } = state\n setWindowScroll(posX, posY)\n }\n }, [currentPageKey])\n\n useImperativeHandle(\n ref,\n () => {\n return {\n navigateTo,\n }\n },\n []\n )\n\n const onHistoryChange = ({ location, action }: Update): void => {\n const state = location.state as HistoryState\n\n if (action !== 'POP') {\n return\n }\n\n if (!state && location.hash !== '') {\n const nextPageKey = urlToPageKey(location.pathname + location.search)\n const containsKey = !!pages[nextPageKey]\n if (containsKey) {\n history.replace(\n {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n },\n {\n pageKey: nextPageKey,\n superglue: true,\n posY: window.pageYOffset,\n posX: window.pageXOffset,\n }\n )\n }\n }\n\n if (state && 'superglue' in state) {\n const { pageKey } = state\n const prevPageKey = store.getState().superglue.currentPageKey\n const containsKey = !!pages[pageKey]\n\n if (containsKey) {\n const { restoreStrategy } = pages[pageKey]\n\n switch (restoreStrategy) {\n case 'fromCacheOnly':\n dispatch(setActivePage({ pageKey }))\n break\n case 'fromCacheAndRevisitInBackground':\n dispatch(setActivePage({ pageKey }))\n visit(pageKey, { revisit: true })\n break\n case 'revisitOnly':\n default:\n visit(pageKey, { revisit: true }).then(() => {\n const noNav =\n prevPageKey === store.getState().superglue.currentPageKey\n if (noNav) {\n // When \"POP'ed\", revisiting (using revisit: true) a page can result in\n // a redirect, or a render of the same page.\n //\n // When its a redirect, calculateNavAction will correctly set the\n // navigationAction to `replace` this is the noop scenario.\n //\n // When its the same page, navigationAction is set to `none` and\n // no navigation took place. In that case, we have to set the\n // activePage otherwise the user is stuck on the original page.\n dispatch(setActivePage({ pageKey }))\n }\n })\n }\n } else {\n visit(pageKey, { revisit: true }).then(() => {\n const noNav =\n prevPageKey === store.getState().superglue.currentPageKey\n if (noNav) {\n dispatch(setActivePage({ pageKey }))\n }\n })\n }\n }\n }\n\n const navigateTo: NavigateTo = (\n path,\n { action } = {\n action: 'push',\n }\n ) => {\n if (action === 'none') {\n return false\n }\n\n const nextPageKey = urlToPageKey(path)\n const hasPage = Object.prototype.hasOwnProperty.call(\n store.getState().pages,\n nextPageKey\n )\n\n if (hasPage) {\n const location = history.location\n const state = location.state as HistoryState\n const historyArgs = [\n path,\n {\n pageKey: nextPageKey,\n superglue: true,\n posY: 0,\n posX: 0,\n },\n ] as const\n\n if (action === 'push') {\n if (hasWindow) {\n history.replace(\n {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n },\n {\n ...state,\n posY: window.scrollY,\n posX: window.scrollX,\n }\n )\n }\n\n history.push(...historyArgs)\n dispatch(setActivePage({ pageKey: nextPageKey }))\n }\n\n if (action === 'replace') {\n history.replace(...historyArgs)\n\n if (currentPageKey !== nextPageKey) {\n dispatch(setActivePage({ pageKey: nextPageKey }))\n dispatch(removePage({ pageKey: currentPageKey }))\n }\n }\n return true\n } else {\n console.warn(\n `\\`navigateTo\\` was called , but could not find\n the pageKey in the store. This may happen when the wrong\n content_location was set in your non-get controller action.\n No navigation will take place`\n )\n return false\n }\n }\n\n const { search } = superglue\n const { componentIdentifier } = pages[currentPageKey]\n const Component = mapping[componentIdentifier]\n\n if (Component) {\n return (\n <NavigationContext.Provider\n value={{ pageKey: currentPageKey, search, navigateTo, visit, remote }}\n >\n <Component />\n </NavigationContext.Provider>\n )\n } else {\n notFound(componentIdentifier)\n }\n})\n\nexport { NavigationContext, NavigationProvider }\n","import { setIn, getIn, urlToPageKey, parsePageKey } from '../utils'\nimport type { Action } from '@reduxjs/toolkit'\nimport {\n saveResponse,\n handleGraft,\n historyChange,\n copyPage,\n setCSRFToken,\n setActivePage,\n removePage,\n} from '../actions'\nimport { config } from '../config'\nimport {\n AllPages,\n Page,\n VisitResponse,\n Fragment,\n GraftResponse,\n SuperglueState,\n JSONMappable,\n} from '../types'\n\nfunction addPlaceholdersToDeferredNodes(existingPage: Page, page: Page): Page {\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\nfunction constrainPagesSize(state: AllPages) {\n const { maxPages } = config\n const allPageKeys = Object.keys(state)\n const cacheTimesRecentFirst = allPageKeys\n .map((key) => state[key].savedAt)\n .sort((a, b) => b - a)\n\n for (const key of Array.from(allPageKeys)) {\n if (state[key].savedAt <= cacheTimesRecentFirst[maxPages - 1]) {\n delete state[key]\n }\n }\n}\n\nfunction handleSaveResponse(\n state: AllPages,\n pageKey: string,\n page: VisitResponse\n): AllPages {\n state = { ...state }\n\n let nextPage: Page = {\n ...page,\n savedAt: Date.now(),\n }\n\n const existingPage = state[pageKey]\n\n if (existingPage) {\n nextPage = addPlaceholdersToDeferredNodes(existingPage, nextPage)\n }\n constrainPagesSize(state)\n state[pageKey] = nextPage\n\n return state\n}\n\nexport function appendReceivedFragmentsOntoPage(\n state: AllPages,\n pageKey: string,\n receivedFragments: Fragment[]\n): AllPages {\n if (!pageKey) {\n return state\n }\n\n if (receivedFragments.length === 0) {\n return state\n }\n\n const currentPage = state[pageKey]\n const { fragments: prevFragments = [] } = currentPage\n const nextFragments = [...prevFragments]\n const existingKeys: Record<string, boolean> = {}\n prevFragments.forEach((frag) => (existingKeys[frag.path] = true))\n\n receivedFragments.forEach((frag) => {\n if (!existingKeys[frag.path]) {\n nextFragments.push(frag)\n }\n })\n\n const nextPage = {\n ...currentPage,\n fragments: nextFragments,\n }\n\n const nextState = { ...state }\n nextState[pageKey] = nextPage\n\n return nextState\n}\n\nexport function graftNodeOntoPage(\n state: AllPages,\n pageKey: string,\n node: JSONMappable,\n pathToNode: string\n): AllPages {\n if (!node) {\n console.warn(\n 'There was no node returned in the response. Do you have the correct key path in your props_at?'\n )\n return state\n }\n\n if (!pathToNode || !pageKey) {\n return state\n }\n const fullPathToNode = [pageKey, pathToNode].join('.')\n return setIn(state, fullPathToNode, node)\n}\n\nfunction handleGraftResponse(\n state: AllPages,\n pageKey: string,\n page: GraftResponse\n): AllPages {\n const currentPage = state[pageKey]\n if (!currentPage) {\n const error = new Error(\n `Superglue was looking for ${pageKey} in your state, but could not find it in your mapping. Did you forget to pass in a valid pageKey to this.props.remote or this.props.visit?`\n )\n throw error\n }\n const {\n data: receivedNode,\n path: pathToNode,\n fragments: receivedFragments = [],\n } = page\n\n return [\n (nextState: AllPages) =>\n graftNodeOntoPage(nextState, pageKey, receivedNode, pathToNode),\n (nextState: AllPages) =>\n appendReceivedFragmentsOntoPage(nextState, pageKey, receivedFragments),\n ].reduce((memo, fn) => fn(memo), state)\n}\n\nexport function pageReducer(state: AllPages = {}, action: Action): AllPages {\n if (removePage.match(action)) {\n const { pageKey } = action.payload\n const nextState = { ...state }\n delete nextState[pageKey]\n\n return nextState\n }\n\n if (copyPage.match(action)) {\n const nextState = { ...state }\n const { from, to } = action.payload\n\n nextState[urlToPageKey(to)] = JSON.parse(JSON.stringify(nextState[from]))\n\n return nextState\n }\n\n if (handleGraft.match(action)) {\n const { pageKey, page } = action.payload\n\n return handleGraftResponse(state, pageKey, page)\n }\n\n if (saveResponse.match(action)) {\n const { pageKey, page } = action.payload\n const nextState = handleSaveResponse(state, pageKey, page)\n return nextState\n }\n\n return state\n}\n\nexport function superglueReducer(\n state: SuperglueState = {\n currentPageKey: '',\n search: {},\n assets: [],\n },\n action: Action\n): SuperglueState {\n if (setCSRFToken.match(action)) {\n const { csrfToken } = action.payload\n return { ...state, csrfToken: csrfToken }\n }\n\n if (setActivePage.match(action)) {\n const { pageKey } = action.payload\n const { search } = parsePageKey(pageKey)\n\n return {\n ...state,\n search,\n currentPageKey: pageKey,\n }\n }\n\n if (historyChange.match(action)) {\n const { pageKey } = action.payload\n const { search } = parsePageKey(pageKey)\n\n return {\n ...state,\n currentPageKey: pageKey,\n search,\n }\n }\n\n if (saveResponse.match(action)) {\n const {\n page: { csrfToken, assets },\n } = action.payload\n\n return { ...state, csrfToken, assets }\n }\n\n return state\n}\n\nexport const rootReducer = {\n superglue: superglueReducer,\n pages: pageReducer,\n}\n","import { useSelector } from 'react-redux'\nimport { JSONMappable, Page, RootState, SuperglueState } from '../types'\n\n/**\n * A lightweight hook that grabs the superglue state from the store.\n */\nexport function useSuperglue() {\n return useSelector<RootState, SuperglueState>((state) => state.superglue)\n}\n\n/**\n * A lightweight hook that grabs the current page's content from the store.\n */\nexport function useContent<T = JSONMappable>() {\n const superglueState = useSuperglue()\n const currentPageKey = superglueState.currentPageKey\n\n return useSelector<RootState<T>, Page<T>>(\n (state) => state.pages[currentPageKey]\n ).data\n}\n"],"mappings":"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","names":["React","NavigationProvider","useSelector","hasWindow","React"]}
|
|
1
|
+
{"version":3,"sources":["../lib/index.tsx","../lib/components/Navigation.tsx","../lib/reducers/index.ts","../lib/hooks/index.ts"],"sourcesContent":["import React, { useRef, useMemo } from 'react'\nimport { config } from './config'\nimport { urlToPageKey, ujsHandlers, argsForHistory } from './utils'\nimport { saveAndProcessPage } from './action_creators'\nimport { historyChange, setCSRFToken } from './actions'\nimport { Provider } from 'react-redux'\n\nimport { createBrowserHistory, createMemoryHistory } from 'history'\n\nimport { NavigationProvider } from './components/Navigation'\nexport { NavigationProvider, NavigationContext } from './components/Navigation'\nexport { saveAndProcessPage } from './action_creators'\nexport {\n beforeFetch,\n beforeVisit,\n beforeRemote,\n updateFragments,\n copyPage,\n removePage,\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n} from './actions'\nexport * from './types'\n\nimport {\n VisitResponse,\n ApplicationProps,\n NavigateTo,\n SuperglueStore,\n SetupProps,\n} from './types'\nexport { superglueReducer, pageReducer, rootReducer } from './reducers'\nexport { getIn } from './utils/immutability'\nexport { urlToPageKey }\nexport * from './hooks'\n\nconst hasWindow = typeof window !== 'undefined'\n\nconst createHistory = () => {\n if (hasWindow) {\n // This is used for client side rendering\n return createBrowserHistory({})\n } else {\n // This is used for server side rendering\n return createMemoryHistory({})\n }\n}\n\nexport const prepareStore = (\n store: SuperglueStore,\n initialPage: VisitResponse,\n path: string\n) => {\n const initialPageKey = urlToPageKey(path)\n const { csrfToken } = initialPage\n\n store.dispatch(\n historyChange({\n pageKey: initialPageKey,\n })\n )\n store.dispatch(saveAndProcessPage(initialPageKey, initialPage))\n store.dispatch(setCSRFToken({ csrfToken }))\n}\n\n/**\n * This is the setup function that the Application calls. Use this function if\n * you like to build your own Application component.\n */\nexport const setup = ({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n navigatorRef,\n}: SetupProps) => {\n config.baseUrl = baseUrl\n\n const { visit, remote } = buildVisitAndRemote(navigatorRef, store)\n\n const initialPageKey = urlToPageKey(path)\n const nextHistory = history || createHistory()\n nextHistory.replace(...argsForHistory(path))\n prepareStore(store, initialPage, path)\n\n const handlers = ujsHandlers({\n visit,\n remote,\n ujsAttributePrefix: 'data-sg',\n store,\n })\n\n return {\n visit,\n remote,\n nextHistory,\n initialPageKey,\n ujs: handlers,\n }\n}\n\n/**\n * The entry point to your superglue application. It sets up the redux Provider,\n * redux state and the Navigation component.\n *\n * This is a simple component, you can override this by copying the source code and\n * use the exported methods used by this component (`start` and `ujsHandler`).\n */\nfunction Application({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n mapping,\n ...rest\n}: ApplicationProps) {\n const navigatorRef = useRef<{ navigateTo: NavigateTo } | null>(null)\n\n const { visit, remote, nextHistory, initialPageKey, ujs } = useMemo(() => {\n return setup({\n initialPage,\n baseUrl,\n path,\n store,\n buildVisitAndRemote,\n history,\n navigatorRef,\n })\n }, [])\n\n // The Nav component is pretty bare and can be inherited from for custom\n // behavior or replaced with your own.\n return (\n <div onClick={ujs.onClick} onSubmit={ujs.onSubmit} {...rest}>\n <Provider store={store}>\n <NavigationProvider\n ref={navigatorRef}\n visit={visit}\n remote={remote}\n mapping={mapping}\n history={nextHistory}\n initialPageKey={initialPageKey}\n />\n </Provider>\n </div>\n )\n}\n\nexport { Application }\n","import React, {\n createContext,\n useEffect,\n useLayoutEffect,\n forwardRef,\n useImperativeHandle,\n ForwardedRef,\n} from 'react'\nimport { urlToPageKey } from '../utils'\nimport { removePage, setActivePage } from '../actions'\nimport {\n HistoryState,\n RootState,\n NavigateTo,\n NavigationContextProps,\n NavigationProviderProps,\n AllPages,\n SuperglueState,\n} from '../types'\nimport { Update } from 'history'\nimport { useDispatch, useSelector, useStore } from 'react-redux'\n\nconst NavigationContext = createContext<NavigationContextProps>(\n {} as NavigationContextProps\n)\n\nconst hasWindow = typeof window !== 'undefined'\n\nconst setWindowScroll = (posX: number, posY: number): void => {\n hasWindow && window.scrollTo(posX, posY)\n}\n\nconst notFound = (identifier: string | undefined): never => {\n let reminder = ''\n if (!identifier) {\n reminder =\n 'Did you forget to add `json.componentIdentifier` in your application.json.props layout?'\n }\n\n const error = new Error(\n `Superglue Nav component was looking for ${identifier} but could not find it in your mapping. ${reminder}`\n )\n\n throw error\n}\n\nconst NavigationProvider = forwardRef(function NavigationProvider(\n { history, visit, remote, mapping }: NavigationProviderProps,\n ref: ForwardedRef<{ navigateTo: NavigateTo | null }>\n) {\n const dispatch = useDispatch()\n const pages = useSelector<RootState, AllPages>((state) => state.pages)\n const superglue = useSelector<RootState, SuperglueState>(\n (state) => state.superglue\n )\n const currentPageKey = useSelector<RootState, string>(\n (state) => state.superglue.currentPageKey\n )\n const store = useStore<RootState>()\n\n useEffect(() => {\n return history.listen(onHistoryChange)\n }, [])\n\n useLayoutEffect(() => {\n const state = history.location.state as HistoryState\n if (state && 'superglue' in state) {\n const { posX, posY } = state\n setWindowScroll(posX, posY)\n }\n }, [currentPageKey])\n\n useImperativeHandle(\n ref,\n () => {\n return {\n navigateTo,\n }\n },\n []\n )\n\n const onHistoryChange = ({ location, action }: Update): void => {\n const state = location.state as HistoryState\n\n if (action !== 'POP') {\n return\n }\n\n if (!state && location.hash !== '') {\n const nextPageKey = urlToPageKey(location.pathname + location.search)\n const containsKey = !!pages[nextPageKey]\n if (containsKey) {\n history.replace(\n {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n },\n {\n pageKey: nextPageKey,\n superglue: true,\n posY: window.pageYOffset,\n posX: window.pageXOffset,\n }\n )\n }\n }\n\n if (state && 'superglue' in state) {\n const { pageKey } = state\n const prevPageKey = store.getState().superglue.currentPageKey\n const containsKey = !!pages[pageKey]\n\n if (containsKey) {\n const { restoreStrategy } = pages[pageKey]\n\n switch (restoreStrategy) {\n case 'fromCacheOnly':\n dispatch(setActivePage({ pageKey }))\n break\n case 'fromCacheAndRevisitInBackground':\n dispatch(setActivePage({ pageKey }))\n visit(pageKey, { revisit: true })\n break\n case 'revisitOnly':\n default:\n visit(pageKey, { revisit: true }).then(() => {\n const noNav =\n prevPageKey === store.getState().superglue.currentPageKey\n if (noNav) {\n // When \"POP'ed\", revisiting (using revisit: true) a page can result in\n // a redirect, or a render of the same page.\n //\n // When its a redirect, calculateNavAction will correctly set the\n // navigationAction to `replace` this is the noop scenario.\n //\n // When its the same page, navigationAction is set to `none` and\n // no navigation took place. In that case, we have to set the\n // activePage otherwise the user is stuck on the original page.\n dispatch(setActivePage({ pageKey }))\n }\n })\n }\n } else {\n visit(pageKey, { revisit: true }).then(() => {\n const noNav =\n prevPageKey === store.getState().superglue.currentPageKey\n if (noNav) {\n dispatch(setActivePage({ pageKey }))\n }\n })\n }\n }\n }\n\n const navigateTo: NavigateTo = (\n path,\n { action } = {\n action: 'push',\n }\n ) => {\n if (action === 'none') {\n return false\n }\n\n const nextPageKey = urlToPageKey(path)\n const hasPage = Object.prototype.hasOwnProperty.call(\n store.getState().pages,\n nextPageKey\n )\n\n if (hasPage) {\n const location = history.location\n const state = location.state as HistoryState\n const historyArgs = [\n path,\n {\n pageKey: nextPageKey,\n superglue: true,\n posY: 0,\n posX: 0,\n },\n ] as const\n\n if (action === 'push') {\n if (hasWindow) {\n history.replace(\n {\n pathname: location.pathname,\n search: location.search,\n hash: location.hash,\n },\n {\n ...state,\n posY: window.scrollY,\n posX: window.scrollX,\n }\n )\n }\n\n history.push(...historyArgs)\n dispatch(setActivePage({ pageKey: nextPageKey }))\n }\n\n if (action === 'replace') {\n history.replace(...historyArgs)\n\n if (currentPageKey !== nextPageKey) {\n dispatch(setActivePage({ pageKey: nextPageKey }))\n dispatch(removePage({ pageKey: currentPageKey }))\n }\n }\n return true\n } else {\n console.warn(\n `\\`navigateTo\\` was called , but could not find\n the pageKey in the store. This may happen when the wrong\n content_location was set in your non-get controller action.\n No navigation will take place`\n )\n return false\n }\n }\n\n const { search } = superglue\n const { componentIdentifier } = pages[currentPageKey]\n const Component = mapping[componentIdentifier]\n\n if (Component) {\n return (\n <NavigationContext.Provider\n value={{ pageKey: currentPageKey, search, navigateTo, visit, remote }}\n >\n <Component />\n </NavigationContext.Provider>\n )\n } else {\n notFound(componentIdentifier)\n }\n})\n\nexport { NavigationContext, NavigationProvider }\n","import { setIn, getIn, urlToPageKey, parsePageKey } from '../utils'\nimport type { Action } from '@reduxjs/toolkit'\nimport {\n saveResponse,\n handleGraft,\n historyChange,\n copyPage,\n setCSRFToken,\n setActivePage,\n removePage,\n} from '../actions'\nimport { config } from '../config'\nimport {\n AllPages,\n Page,\n VisitResponse,\n Fragment,\n GraftResponse,\n SuperglueState,\n JSONMappable,\n} from '../types'\n\nfunction addPlaceholdersToDeferredNodes(existingPage: Page, page: Page): Page {\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\nfunction constrainPagesSize(state: AllPages) {\n const { maxPages } = config\n const allPageKeys = Object.keys(state)\n const cacheTimesRecentFirst = allPageKeys\n .map((key) => state[key].savedAt)\n .sort((a, b) => b - a)\n\n for (const key of Array.from(allPageKeys)) {\n if (state[key].savedAt <= cacheTimesRecentFirst[maxPages - 1]) {\n delete state[key]\n }\n }\n}\n\nfunction handleSaveResponse(\n state: AllPages,\n pageKey: string,\n page: VisitResponse\n): AllPages {\n state = { ...state }\n\n let nextPage: Page = {\n ...page,\n savedAt: Date.now(),\n }\n\n const existingPage = state[pageKey]\n\n if (existingPage) {\n nextPage = addPlaceholdersToDeferredNodes(existingPage, nextPage)\n }\n constrainPagesSize(state)\n state[pageKey] = nextPage\n\n return state\n}\n\nexport function appendReceivedFragmentsOntoPage(\n state: AllPages,\n pageKey: string,\n receivedFragments: Fragment[]\n): AllPages {\n if (!pageKey) {\n return state\n }\n\n if (receivedFragments.length === 0) {\n return state\n }\n\n const currentPage = state[pageKey]\n const { fragments: prevFragments = [] } = currentPage\n const nextFragments = [...prevFragments]\n const existingKeys: Record<string, boolean> = {}\n prevFragments.forEach((frag) => (existingKeys[frag.path] = true))\n\n receivedFragments.forEach((frag) => {\n if (!existingKeys[frag.path]) {\n nextFragments.push(frag)\n }\n })\n\n const nextPage = {\n ...currentPage,\n fragments: nextFragments,\n }\n\n const nextState = { ...state }\n nextState[pageKey] = nextPage\n\n return nextState\n}\n\nexport function graftNodeOntoPage(\n state: AllPages,\n pageKey: string,\n node: JSONMappable,\n pathToNode: string\n): AllPages {\n if (!node) {\n console.warn(\n 'There was no node returned in the response. Do you have the correct key path in your props_at?'\n )\n return state\n }\n\n if (!pathToNode || !pageKey) {\n return state\n }\n const fullPathToNode = [pageKey, pathToNode].join('.')\n return setIn(state, fullPathToNode, node)\n}\n\nfunction handleGraftResponse(\n state: AllPages,\n pageKey: string,\n page: GraftResponse\n): AllPages {\n const currentPage = state[pageKey]\n if (!currentPage) {\n const error = new Error(\n `Superglue was looking for ${pageKey} in your state, but could not find it in your mapping. Did you forget to pass in a valid pageKey to this.props.remote or this.props.visit?`\n )\n throw error\n }\n const {\n data: receivedNode,\n path: pathToNode,\n fragments: receivedFragments = [],\n } = page\n\n return [\n (nextState: AllPages) =>\n graftNodeOntoPage(nextState, pageKey, receivedNode, pathToNode),\n (nextState: AllPages) =>\n appendReceivedFragmentsOntoPage(nextState, pageKey, receivedFragments),\n ].reduce((memo, fn) => fn(memo), state)\n}\n\nexport function pageReducer(state: AllPages = {}, action: Action): AllPages {\n if (removePage.match(action)) {\n const { pageKey } = action.payload\n const nextState = { ...state }\n delete nextState[pageKey]\n\n return nextState\n }\n\n if (copyPage.match(action)) {\n const nextState = { ...state }\n const { from, to } = action.payload\n\n nextState[urlToPageKey(to)] = JSON.parse(JSON.stringify(nextState[from]))\n\n return nextState\n }\n\n if (handleGraft.match(action)) {\n const { pageKey, page } = action.payload\n\n return handleGraftResponse(state, pageKey, page)\n }\n\n if (saveResponse.match(action)) {\n const { pageKey, page } = action.payload\n const nextState = handleSaveResponse(state, pageKey, page)\n return nextState\n }\n\n return state\n}\n\nexport function superglueReducer(\n state: SuperglueState = {\n currentPageKey: '',\n search: {},\n assets: [],\n },\n action: Action\n): SuperglueState {\n if (setCSRFToken.match(action)) {\n const { csrfToken } = action.payload\n return { ...state, csrfToken: csrfToken }\n }\n\n if (setActivePage.match(action)) {\n const { pageKey } = action.payload\n const { search } = parsePageKey(pageKey)\n\n return {\n ...state,\n search,\n currentPageKey: pageKey,\n }\n }\n\n if (historyChange.match(action)) {\n const { pageKey } = action.payload\n const { search } = parsePageKey(pageKey)\n\n return {\n ...state,\n currentPageKey: pageKey,\n search,\n }\n }\n\n if (saveResponse.match(action)) {\n const {\n page: { csrfToken, assets },\n } = action.payload\n\n return { ...state, csrfToken, assets }\n }\n\n return state\n}\n\nexport const rootReducer = {\n superglue: superglueReducer,\n pages: pageReducer,\n}\n","import { useSelector } from 'react-redux'\nimport { JSONMappable, Page, RootState, SuperglueState } from '../types'\n\n/**\n * A lightweight hook that grabs the superglue state from the store.\n */\nexport function useSuperglue() {\n return useSelector<RootState, SuperglueState>((state) => state.superglue)\n}\n\n/**\n * A lightweight hook that grabs the current page's content from the store.\n */\nexport function useContent<T = JSONMappable>() {\n const superglueState = useSuperglue()\n const currentPageKey = superglueState.currentPageKey\n\n return useSelector<RootState<T>, Page<T>>(\n (state) => state.pages[currentPageKey]\n ).data\n}\n"],"mappings":"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","names":["React","NavigationProvider","useSelector","hasWindow","React"]}
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/utils/url.ts","../lib/utils/helpers.ts","../lib/utils/immutability.ts","../lib/config.ts","../lib/utils/request.ts","../lib/utils/ujs.ts","../lib/utils/window.ts","../lib/actions.ts","../lib/action_creators/requests.ts","../lib/action_creators/index.ts"],"sourcesContent":["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","import { GraftResponse, HistoryState, VisitResponse } from '../types'\nimport { urlToPageKey } from './url'\n\nexport function isGraft(page: GraftResponse | VisitResponse): boolean {\n return 'action' in page && page.action === 'graft'\n}\n\nexport function extractNodeAndPath(page: GraftResponse): {\n node: unknown\n pathToNode: string\n} {\n const { data: node, action, path: pathToNode } = page\n\n if (action === 'graft') {\n return { node, pathToNode }\n } else {\n const errMsg =\n 'Expected page to be a graft response rendered from node filtering.'\n throw new Error(errMsg)\n }\n}\n\nexport function argsForHistory(path: string): [string, HistoryState] {\n const pageKey = urlToPageKey(path)\n\n return [\n path,\n {\n superglue: true,\n pageKey,\n posX: 0,\n posY: 0,\n },\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","import { formatForXHR } from './url'\nimport { config } from '../config'\nimport { BasicRequestInit, ParsedResponse, RootState } from '../types'\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 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","import {\n Handlers,\n UJSHandlers,\n SuperglueStore,\n ApplicationVisit,\n ApplicationRemote,\n RemoteProps,\n VisitProps,\n} from '../types'\n\nexport class HandlerBuilder {\n public attributePrefix: string\n public visit: ApplicationVisit\n public remote: ApplicationRemote\n private store: SuperglueStore\n\n constructor({\n ujsAttributePrefix,\n visit,\n remote,\n store,\n }: {\n ujsAttributePrefix: string\n visit: ApplicationVisit\n remote: ApplicationRemote\n store: SuperglueStore\n }) {\n this.attributePrefix = ujsAttributePrefix\n this.isUJS = this.isUJS.bind(this)\n this.store = store\n\n this.handleSubmit = this.handleSubmit.bind(this)\n this.handleClick = this.handleClick.bind(this)\n\n this.visit = visit\n this.remote = remote\n this.visitOrRemote = this.visitOrRemote.bind(this)\n }\n\n retrieveLink(target: Element): HTMLAnchorElement | undefined {\n const link = target.closest<HTMLAnchorElement>('a')\n if (link && link.href.length !== 0) {\n return link\n }\n }\n\n isNonStandardClick(\n event: React.MouseEvent<HTMLDivElement, MouseEvent>\n ): boolean {\n return (\n event.button > 0 ||\n event.metaKey ||\n event.ctrlKey ||\n event.shiftKey ||\n event.altKey\n )\n }\n\n isUJS(node: HTMLFormElement | HTMLAnchorElement): boolean {\n const hasVisit = !!node.getAttribute(this.attributePrefix + '-visit')\n const hasRemote = !!node.getAttribute(this.attributePrefix + '-remote')\n\n return hasVisit || hasRemote\n }\n\n handleSubmit(event: React.FormEvent<HTMLDivElement>): void {\n const form = event.target\n\n if (!(form instanceof HTMLFormElement)) {\n return\n }\n\n if (!this.isUJS(form)) {\n return\n }\n\n event.preventDefault()\n\n const url = form.getAttribute('action')\n if (!url) {\n return\n }\n\n const method = (form.getAttribute('method') || 'POST').toUpperCase()\n\n this.visitOrRemote(form, url, {\n method,\n body: new FormData(form),\n })\n }\n\n handleClick(event: React.MouseEvent<HTMLDivElement, MouseEvent>): void {\n if (!(event.target instanceof Element)) {\n return\n }\n\n const link = this.retrieveLink(event.target)\n const isNonStandard = this.isNonStandardClick(event)\n if (!link || isNonStandard || !this.isUJS(link)) {\n return\n }\n\n event.preventDefault()\n const url = link.getAttribute('href')\n if (!url) {\n return\n }\n\n this.visitOrRemote(link, url, { method: 'GET' })\n }\n\n visitOrRemote(\n linkOrForm: HTMLAnchorElement | HTMLFormElement,\n url: string,\n opts: RemoteProps | VisitProps\n ): void {\n const dataset = { ...linkOrForm.dataset }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-visit')) {\n this.visit(url, { ...opts, dataset })\n }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-remote')) {\n const { currentPageKey } = this.store.getState().superglue\n this.remote(url, {\n ...opts,\n pageKey: currentPageKey,\n dataset,\n })\n }\n }\n\n handlers(): Handlers {\n return {\n onClick: this.handleClick,\n onSubmit: this.handleSubmit,\n }\n }\n}\n\nexport const ujsHandlers: UJSHandlers = ({\n ujsAttributePrefix,\n visit,\n remote,\n store,\n}) => {\n const builder = new HandlerBuilder({\n visit,\n remote,\n ujsAttributePrefix,\n store,\n })\n\n return builder.handlers()\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 VisitResponse,\n JSONMappable,\n Keypath,\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: VisitResponse }) => {\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 called whenever a fragment is received from `visit` or updated\n * using `remote`. Its a useful action to use for cross cutting concerns like a\n * shared header or a shopping cart. For example:\n *\n * ```\n * import { updateFragments } from '@thoughtbot/superglue'\n *\n * export const exampleSlice = createSlice({\n * name: 'Example',\n * initialState: {},\n * extraReducers: (builder) => {\n * builder.addCase(updateFragments, (state, action) => {\n * // Update the slice using the latest and greatest.\n * return action.value\n * ```\n */\nexport const updateFragments = createAction<{\n name: string\n path: Keypath\n pageKey: PageKey\n value: JSONMappable\n previousValue?: JSONMappable\n}>('@@superglue/UPDATE_FRAGMENTS')\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","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} from '../actions'\nimport { saveAndProcessPage } from './index'\nimport {\n FetchArgs,\n VisitResponse,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n NavigationAction,\n VisitMeta,\n} from '../types'\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(superglueError({ message: err.message }))\n throw err\n}\n\nfunction buildMeta(\n pageKey: string,\n page: VisitResponse,\n state: SuperglueState,\n rsp: Response,\n fetchArgs: FetchArgs\n): Meta {\n const { assets: prevAssets } = state\n const { assets: nextAssets } = page\n\n return {\n pageKey,\n page,\n redirected: rsp.redirected,\n rsp,\n fetchArgs,\n componentIdentifier: page.componentIdentifier,\n needsRefresh: needsRefresh(prevAssets, nextAssets),\n }\n}\n\nexport class MismatchedComponentError extends Error {\n constructor(message: string) {\n super(message)\n this.name = 'MismatchedComponentError'\n }\n}\n\nexport const remote: RemoteCreator = (\n path,\n {\n pageKey: targetPageKey,\n force = false,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\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 = {} } = 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 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 const page = beforeSave(pages[pageKey], json)\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 = {} } = getState()\n const isGet = fetchArgs[1].method === 'GET'\n const pageKey = calculatePageKey(rsp, isGet, currentPageKey)\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 meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n const visitMeta: VisitMeta = {\n ...meta,\n navigationAction: calculateNavAction(\n meta,\n rsp,\n isGet,\n pageKey,\n currentPageKey,\n revisit\n ),\n }\n\n const page = beforeSave(pages[pageKey], json)\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 isGet: boolean,\n pageKey: string,\n currentPageKey: string,\n revisit: boolean\n) {\n let navigationAction: NavigationAction = 'push'\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 { urlToPageKey, getIn, propsAtParam } from '../utils'\nimport {\n saveResponse,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n updateFragments,\n handleGraft,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n VisitResponse,\n SaveAndProcessPageThunk,\n DefermentThunk,\n GraftResponse,\n Defer,\n JSONMappable,\n} from '../types'\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\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: VisitResponse | GraftResponse\n): SaveAndProcessPageThunk {\n return (dispatch, getState) => {\n pageKey = urlToPageKey(pageKey)\n\n const { defers = [] } = page\n\n if ('action' in page) {\n const prevPage = getState().pages[pageKey]\n dispatch(handleGraft({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n // A fragment only works on a block in props_template. So using getIn\n // will always return a JSONMappable\n const currentFragment = getIn(currentPage, path) as JSONMappable\n const prevFragment = getIn(prevPage, path) as JSONMappable\n if (!prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n } else if (currentFragment !== prevFragment) {\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n previousValue: prevFragment,\n path,\n })\n )\n }\n })\n } else {\n dispatch(saveResponse({ pageKey, page }))\n const currentPage = getState().pages[pageKey]\n\n currentPage.fragments.forEach((fragment) => {\n const { type, path } = fragment\n const currentFragment = getIn(currentPage, path) as JSONMappable\n\n dispatch(\n updateFragments({\n name: type,\n pageKey: pageKey,\n value: currentFragment,\n path,\n })\n )\n })\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, defers)).then(() =>\n Promise.resolve()\n )\n } else {\n return Promise.resolve()\n }\n }\n}\n"],"mappings":"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","names":["pathQuery","visit","remote"]}
|