@thoughtbot/superglue 0.53.4 → 0.54.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../lib/utils/url.ts","../lib/utils/helpers.ts","../lib/utils/immutability.ts","../lib/utils/react.ts","../lib/utils/request.ts","../lib/config.ts","../lib/utils/ujs.ts","../lib/utils/window.ts","../lib/action_creators/index.ts","../lib/actions.ts","../lib/action_creators/requests.ts"],"sourcesContent":["import parse from 'url-parse'\nimport { PageKey } from '../types'\n\nexport function pathQuery(url: string): string {\n const { pathname, query } = new parse(url, {})\n\n return pathname + query\n}\n\nexport function pathQueryHash(url: string): string {\n const { pathname, query, hash } = new parse(url, {})\n\n return pathname + query + hash\n}\n\nexport function hasPropsAt(url: string): boolean {\n const parsed = new parse(url, {}, true)\n const query = parsed.query\n\n return !!query['props_at']\n}\n\nexport function withFormatJson(url: string): string {\n const parsed = new parse(url, {}, true)\n parsed.query['format'] = 'json'\n\n return parsed.toString()\n}\n\nexport function pathWithoutBZParams(url: string): string {\n const parsed = new parse(url, {}, true)\n const query = parsed.query\n\n delete query['props_at']\n delete query['format']\n parsed.set('query', query)\n\n return pathQueryHash(parsed.toString())\n}\n\nexport function removePropsAt(url: string): string {\n const parsed = new parse(url, {}, true)\n const query = parsed.query\n\n delete query['props_at']\n parsed.set('query', query)\n\n return parsed.toString()\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 parse(url, {}, true)\n const query = parsed.query\n\n delete query['props_at']\n delete query['format']\n parsed.set('query', query)\n\n return pathQuery(parsed.toString())\n}\n\nexport function withoutHash(url: string): string {\n const parsed = new parse(url, {}, true)\n parsed.set('hash', '')\n return parsed.toString()\n}\n\nexport function withoutBusters(url: string): string {\n const parsed = new parse(url, {}, true)\n const query = parsed.query\n delete query['format']\n parsed.set('query', query)\n\n return pathQuery(parsed.toString())\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","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 { saveAndProcessPage, copyPage } from '../action_creators'\nimport { Content, PageOwnProps, RootState } from '../types'\nimport { urlToPageKey } from './url'\n\nexport function mapStateToProps(\n state: RootState,\n ownProps: PageOwnProps\n): Content {\n let pageKey = ownProps.pageKey\n const params = ownProps\n const csrfToken = state.superglue.csrfToken\n pageKey = urlToPageKey(pageKey)\n const { data, fragments } = state.pages[pageKey] || {\n data: {},\n fragments: [],\n }\n return { ...data, ...params, pageKey, csrfToken, fragments }\n}\n\nexport const mapDispatchToProps = {\n saveAndProcessPage,\n copyPage,\n}\n","import parse from 'url-parse'\nimport { 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) {\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 { method = 'GET', headers = {}, body = '', signal }: 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 parse(\n formatForXHR(pathQuery),\n config.baseUrl || {},\n true\n )\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 parse(\n currentState.currentPageKey,\n config.baseUrl || {},\n false\n ).href\n\n options.referrer = referrer\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 // TODO: Add coverage for this\n const nextQuery = { ...fetchPath.query, ...Object.fromEntries(allData) }\n fetchPath.set('query', nextQuery)\n }\n\n delete options.body\n }\n\n return [fetchPath.toString(), options]\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 const config = {\n baseUrl: '',\n maxPages: 20,\n}\n","import { withoutBusters, urlToPageKey } from './url'\nimport {\n Visit,\n Remote,\n VisitProps,\n RemoteProps,\n Meta,\n Handlers,\n UJSHandlers,\n} from '../types'\n\nexport class HandlerBuilder {\n public attributePrefix: string\n public visit: Visit\n public remote: Remote\n\n constructor({\n ujsAttributePrefix,\n visit,\n remote,\n }: {\n ujsAttributePrefix: string\n visit: Visit\n remote: Remote\n }) {\n this.attributePrefix = ujsAttributePrefix\n this.isUJS = this.isUJS.bind(this)\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(event: MouseEvent): boolean {\n return (\n event.which > 1 ||\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: Event): 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 let url = form.getAttribute('action')\n if (!url) {\n return\n }\n\n const method = (form.getAttribute('method') || 'POST').toUpperCase()\n url = withoutBusters(url)\n\n this.visitOrRemote(form, url, {\n method,\n body: new FormData(form),\n })\n }\n\n handleClick(event: 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 let url = link.getAttribute('href')\n if (!url) {\n return\n }\n url = withoutBusters(url)\n\n this.visitOrRemote(link, url, { method: 'GET' })\n }\n\n visitOrRemote(\n linkOrForm: HTMLAnchorElement | HTMLFormElement,\n url: string,\n opts: VisitProps | RemoteProps\n ): Promise<Meta> | undefined {\n if (linkOrForm.getAttribute(this.attributePrefix + '-visit')) {\n const nextOpts: VisitProps = { ...opts }\n const placeholderKey = linkOrForm.getAttribute(\n this.attributePrefix + '-placeholder'\n )\n if (placeholderKey) {\n nextOpts.placeholderKey = urlToPageKey(placeholderKey)\n }\n return this.visit(url, { ...nextOpts })\n }\n\n if (linkOrForm.getAttribute(this.attributePrefix + '-remote')) {\n return this.remote(url, opts)\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}) => {\n const builder = new HandlerBuilder({\n visit,\n remote,\n ujsAttributePrefix,\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 { urlToPageKey, getIn } from '../utils'\nimport parse from 'url-parse'\nimport {\n SAVE_RESPONSE,\n HANDLE_GRAFT,\n GRAFTING_ERROR,\n GRAFTING_SUCCESS,\n COPY_PAGE,\n UPDATE_FRAGMENTS,\n} from '../actions'\nimport { remote } from './requests'\nimport {\n CopyAction,\n VisitResponse,\n SaveResponseAction,\n UpdateFragmentsAction,\n SaveAndProcessPageThunk,\n DefermentThunk,\n HandleGraftAction,\n GraftResponse,\n Page,\n Defer,\n JSONMappable,\n} from '../types'\nexport * from './requests'\n\nexport function copyPage({\n from,\n to,\n}: {\n from: string\n to: string\n}): CopyAction {\n return {\n type: COPY_PAGE,\n payload: {\n from,\n to,\n },\n }\n}\n\nexport function saveResponse({\n pageKey,\n page,\n}: {\n pageKey: string\n page: VisitResponse\n}): SaveResponseAction {\n pageKey = urlToPageKey(pageKey)\n\n return {\n type: SAVE_RESPONSE,\n payload: {\n pageKey,\n page,\n },\n }\n}\n\nexport function handleGraft({\n pageKey,\n page,\n}: {\n pageKey: string\n page: GraftResponse\n}): HandleGraftAction {\n pageKey = urlToPageKey(pageKey)\n\n return {\n type: HANDLE_GRAFT,\n payload: {\n pageKey,\n page,\n },\n }\n}\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 const parsedUrl = new parse(url, true)\n\n // props_at will always be present in a graft response\n // That's why this is marked `as string`\n const keyPath = parsedUrl.query.props_at as string\n\n return dispatch(remote(url, { pageKey }))\n .then(() => {\n dispatch({\n type: successAction,\n payload: {\n pageKey,\n keyPath,\n },\n })\n })\n .catch((err) => {\n dispatch({\n type: failAction,\n payload: {\n url,\n err,\n pageKey,\n keyPath,\n },\n })\n })\n })\n\n return Promise.all(fetches)\n }\n}\n\nfunction updateFragmentsUsing(page: Page): UpdateFragmentsAction {\n const changedFragments: Record<string, JSONMappable> = {}\n page.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 changedFragments[type] = getIn(page, path) as JSONMappable\n })\n\n return {\n type: UPDATE_FRAGMENTS,\n payload: { changedFragments },\n }\n}\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 dispatch(handleGraft({ pageKey, page }))\n } else {\n dispatch(saveResponse({ pageKey, page }))\n }\n\n const hasFetch = typeof fetch != 'undefined'\n if (hasFetch) {\n return dispatch(fetchDeferments(pageKey, defers)).then(() => {\n if (page.fragments.length > 0) {\n const finishedPage = getState().pages[pageKey]\n dispatch(updateFragmentsUsing(finishedPage))\n return Promise.resolve()\n }\n })\n } else {\n return Promise.resolve()\n }\n }\n}\n","export const BEFORE_FETCH = '@@superglue/BEFORE_FETCH'\nexport const BEFORE_VISIT = '@@superglue/BEFORE_VISIT'\nexport const BEFORE_REMOTE = '@@superglue/BEFORE_REMOTE'\n\nexport const SAVE_RESPONSE = '@@superglue/SAVE_RESPONSE'\nexport const HANDLE_GRAFT = '@@superglue/HANDLE_GRAFT'\n\nexport const SUPERGLUE_ERROR = '@@superglue/ERROR'\nexport const GRAFTING_ERROR = '@@superglue/GRAFTING_ERROR'\nexport const GRAFTING_SUCCESS = '@@superglue/GRAFTING_SUCCESS'\n\nexport const HISTORY_CHANGE = '@@superglue/HISTORY_CHANGE'\nexport const SET_CSRF_TOKEN = '@@superglue/SET_CSRF_TOKEN'\nexport const REMOVE_PAGE = '@@superglue/REMOVE_PAGE'\nexport const COPY_PAGE = '@@superglue/COPY_PAGE'\nexport const UPDATE_FRAGMENTS = '@@superglue/UPDATE_FRAGMENTS'\n","import {\n argsForFetch,\n parseResponse,\n needsRefresh,\n urlToPageKey,\n withoutBusters,\n hasPropsAt,\n removePropsAt,\n} from '../utils'\nimport {\n BEFORE_FETCH,\n BEFORE_VISIT,\n BEFORE_REMOTE,\n SUPERGLUE_ERROR,\n} from '../actions'\nimport { copyPage, saveAndProcessPage } from './index'\nimport {\n BeforeVisit,\n BeforeFetch,\n FetchArgs,\n BeforeRemote,\n HandleError,\n VisitResponse,\n PageResponse,\n Page,\n SuperglueState,\n Meta,\n Dispatch,\n RemoteCreator,\n VisitCreator,\n} from '../types'\n\nfunction beforeVisit(payload: {\n fetchArgs: FetchArgs\n currentPageKey: string\n}): BeforeVisit {\n return {\n type: BEFORE_VISIT,\n payload,\n }\n}\n\nfunction beforeRemote(payload: {\n fetchArgs: FetchArgs\n currentPageKey: string\n}): BeforeRemote {\n return {\n type: BEFORE_REMOTE,\n payload,\n }\n}\n\nfunction beforeFetch(payload: { fetchArgs: FetchArgs }): BeforeFetch {\n return {\n type: BEFORE_FETCH,\n payload,\n }\n}\n\nfunction handleError(err: Error): HandleError {\n return {\n type: SUPERGLUE_ERROR,\n payload: {\n message: err.message,\n },\n }\n}\n\nfunction handleFetchErr(\n err: Error,\n fetchArgs: FetchArgs,\n dispatch: Dispatch\n): never {\n dispatch(handleError(err))\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 const remote: RemoteCreator = (\n path,\n {\n method = 'GET',\n headers,\n body,\n pageKey: rawPageKey,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\n } = {}\n) => {\n path = withoutBusters(path)\n rawPageKey = rawPageKey && urlToPageKey(rawPageKey)\n\n return (dispatch, getState) => {\n const fetchArgs = argsForFetch(getState, path, {\n method,\n headers,\n body,\n })\n if (rawPageKey === undefined) {\n rawPageKey = getState().superglue.currentPageKey\n }\n const pageKey = rawPageKey\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 const meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n const willReplaceCurrent = pageKey == currentPageKey\n const existingId = pages[currentPageKey]?.componentIdentifier\n const receivedId = json.componentIdentifier\n\n if (willReplaceCurrent && !!existingId && existingId != receivedId) {\n console.warn(\n `You're about replace an existing page located at pages[\"${currentPageKey}\"]\nthat has the componentIdentifier \"${existingId}\" with the contents of a\nreceived page that has a componentIdentifier of \"${receivedId}\".\n\nThis can happen if you're using data-sg-remote or remote but your response\nredirected to a completely different page. Since remote requests do not\nnavigate or change the current page component, your current page component may\nreceive a shape that is unexpected and cause issues with rendering.\n\nConsider using data-sg-visit, the visit function, or redirect_back.`\n )\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 abort: () => {\n // noop\n },\n}\n\nexport const visit: VisitCreator = (\n path,\n {\n method = 'GET',\n headers,\n body,\n placeholderKey,\n beforeSave = (prevPage: Page, receivedPage: PageResponse) => receivedPage,\n revisit = false,\n } = {}\n) => {\n path = withoutBusters(path)\n let pageKey = urlToPageKey(path)\n\n return (dispatch, getState) => {\n placeholderKey = placeholderKey && urlToPageKey(placeholderKey)\n const hasPlaceholder = !!(\n placeholderKey && getState().pages[placeholderKey]\n )\n\n if (placeholderKey && hasPlaceholder) {\n dispatch(copyPage({ from: placeholderKey, to: pageKey }))\n }\n\n if (placeholderKey && !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 if (!placeholderKey && hasPropsAt(path)) {\n console.warn(\n `visit was called with props_at param in the path ${path}, this will be ignore unless you provide a placeholder.`\n )\n path = removePropsAt(path)\n }\n\n const controller = new AbortController()\n const { signal } = controller\n const fetchArgs = argsForFetch(getState, path, {\n headers,\n body,\n method,\n signal,\n })\n\n const currentPageKey = getState().superglue.currentPageKey\n dispatch(beforeVisit({ currentPageKey, fetchArgs }))\n dispatch(beforeFetch({ fetchArgs }))\n\n lastVisitController.abort()\n lastVisitController = controller\n\n return fetch(...fetchArgs)\n .then(parseResponse)\n .then(({ rsp, json }) => {\n const { superglue, pages = {} } = getState()\n\n const meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs)\n\n const isGet = fetchArgs[1].method === 'GET'\n\n meta.suggestedAction = 'push'\n if (!rsp.redirected && !isGet) {\n meta.suggestedAction = 'replace'\n }\n\n if (revisit && isGet) {\n if (rsp.redirected) {\n meta.suggestedAction = 'replace'\n } else {\n meta.suggestedAction = 'none'\n }\n }\n\n pageKey = urlToPageKey(rsp.url)\n\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\n const page = beforeSave(pages[pageKey], json)\n return dispatch(saveAndProcessPage(pageKey, page)).then(() => {\n meta.pageKey = pageKey\n return meta\n })\n })\n .catch((e) => handleFetchErr(e, fetchArgs, dispatch))\n }\n}\n"],"mappings":"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","names":["parse","pathQuery","parse","visit","remote","parse","parse"]}
@@ -0,0 +1,597 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // lib/action_creators/index.ts
31
+ var action_creators_exports = {};
32
+ __export(action_creators_exports, {
33
+ copyPage: () => copyPage,
34
+ handleGraft: () => handleGraft,
35
+ remote: () => remote,
36
+ saveAndProcessPage: () => saveAndProcessPage,
37
+ saveResponse: () => saveResponse,
38
+ visit: () => visit
39
+ });
40
+ module.exports = __toCommonJS(action_creators_exports);
41
+
42
+ // lib/utils/url.ts
43
+ var import_url_parse = __toESM(require("url-parse"));
44
+ function pathQuery(url) {
45
+ const { pathname, query } = new import_url_parse.default(url, {});
46
+ return pathname + query;
47
+ }
48
+ function hasPropsAt(url) {
49
+ const parsed = new import_url_parse.default(url, {}, true);
50
+ const query = parsed.query;
51
+ return !!query["props_at"];
52
+ }
53
+ function withFormatJson(url) {
54
+ const parsed = new import_url_parse.default(url, {}, true);
55
+ parsed.query["format"] = "json";
56
+ return parsed.toString();
57
+ }
58
+ function removePropsAt(url) {
59
+ const parsed = new import_url_parse.default(url, {}, true);
60
+ const query = parsed.query;
61
+ delete query["props_at"];
62
+ parsed.set("query", query);
63
+ return parsed.toString();
64
+ }
65
+ function urlToPageKey(url) {
66
+ const parsed = new import_url_parse.default(url, {}, true);
67
+ const query = parsed.query;
68
+ delete query["props_at"];
69
+ delete query["format"];
70
+ parsed.set("query", query);
71
+ return pathQuery(parsed.toString());
72
+ }
73
+ function withoutHash(url) {
74
+ const parsed = new import_url_parse.default(url, {}, true);
75
+ parsed.set("hash", "");
76
+ return parsed.toString();
77
+ }
78
+ function withoutBusters(url) {
79
+ const parsed = new import_url_parse.default(url, {}, true);
80
+ const query = parsed.query;
81
+ delete query["format"];
82
+ parsed.set("query", query);
83
+ return pathQuery(parsed.toString());
84
+ }
85
+ function formatForXHR(url) {
86
+ const formats = [withoutHash, withFormatJson];
87
+ return formats.reduce((memo, f) => f(memo), url);
88
+ }
89
+
90
+ // lib/utils/immutability.ts
91
+ var canLookAhead = /^[\da-zA-Z\-_]+=[\da-zA-Z\-_]+$/;
92
+ var KeyPathError = class extends Error {
93
+ constructor(message) {
94
+ super(message);
95
+ this.name = "KeyPathError";
96
+ }
97
+ };
98
+ function getIn(node, path) {
99
+ const keyPath = normalizeKeyPath(path);
100
+ let result = node;
101
+ let i;
102
+ for (i = 0; i < keyPath.length; i++) {
103
+ const key = keyPath[i];
104
+ if (typeof result === "object" && result !== null) {
105
+ if (!Array.isArray(result) && canLookAhead.test(key)) {
106
+ throw new KeyPathError(
107
+ `Expected to find an Array when using the key: ${key}`
108
+ );
109
+ }
110
+ result = atKey(result, key);
111
+ } else {
112
+ throw new KeyPathError(
113
+ `Expected to traverse an Array or Obj, got ${JSON.stringify(result)}`
114
+ );
115
+ }
116
+ }
117
+ if (i === keyPath.length) {
118
+ return result;
119
+ } else {
120
+ return void 0;
121
+ }
122
+ }
123
+ function getKey(node, key) {
124
+ if (Array.isArray(node) && Number.isNaN(Number(key))) {
125
+ const key_parts = Array.from(key.split("="));
126
+ const attr = key_parts[0];
127
+ const id = key_parts[1];
128
+ if (!id || !attr) {
129
+ return key;
130
+ }
131
+ let i;
132
+ let child;
133
+ for (i = 0; i < node.length; i++) {
134
+ child = node[i];
135
+ if (typeof child === "object" && !Array.isArray(child) && child !== null) {
136
+ const val = child[attr];
137
+ if (val && val.toString() === id) {
138
+ break;
139
+ }
140
+ } else {
141
+ throw new KeyPathError(`Could not look ahead ${key} at ${child}`);
142
+ }
143
+ }
144
+ if (i === node.length) {
145
+ throw new KeyPathError(`Could not find ${key} while looking ahead`);
146
+ }
147
+ return i;
148
+ } else {
149
+ return key;
150
+ }
151
+ }
152
+ function atKey(node, key) {
153
+ const actualKey = getKey(node, key);
154
+ if (Array.isArray(node)) {
155
+ return node[actualKey];
156
+ } else {
157
+ return node[actualKey];
158
+ }
159
+ }
160
+ function normalizeKeyPath(path) {
161
+ if (typeof path === "string") {
162
+ path = path.replace(/ /g, "");
163
+ if (path === "") {
164
+ return [];
165
+ }
166
+ return path.split(".");
167
+ } else {
168
+ return path;
169
+ }
170
+ }
171
+
172
+ // lib/utils/request.ts
173
+ var import_url_parse2 = __toESM(require("url-parse"));
174
+
175
+ // lib/config.ts
176
+ var config = {
177
+ baseUrl: "",
178
+ maxPages: 20
179
+ };
180
+
181
+ // lib/utils/request.ts
182
+ function isValidResponse(xhr) {
183
+ return isValidContent(xhr) && !downloadingFile(xhr);
184
+ }
185
+ function isValidContent(rsp) {
186
+ const contentType = rsp.headers.get("content-type");
187
+ const jsContent = /^(?:application\/json)(?:;|$)/;
188
+ return !!(contentType && contentType.match(jsContent));
189
+ }
190
+ function downloadingFile(xhr) {
191
+ const disposition = xhr.headers.get("content-disposition");
192
+ return !!(disposition && disposition.match(/^attachment/) !== null);
193
+ }
194
+ var SuperglueResponseError = class extends Error {
195
+ constructor(message) {
196
+ super(message);
197
+ this.name = "SuperglueResponseError";
198
+ }
199
+ };
200
+ function validateResponse(args) {
201
+ const { rsp } = args;
202
+ if (isValidResponse(rsp)) {
203
+ return args;
204
+ } else {
205
+ const error = new SuperglueResponseError("Invalid Superglue Response");
206
+ error.response = rsp;
207
+ throw error;
208
+ }
209
+ }
210
+ function handleServerErrors(args) {
211
+ const { rsp } = args;
212
+ if (!rsp.ok) {
213
+ if (rsp.status === 406) {
214
+ console.error(
215
+ "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\nrespond_to do |format|\n format.html\n format.json\n format.csv\nend"
216
+ );
217
+ }
218
+ const error = new SuperglueResponseError(rsp.statusText);
219
+ error.response = rsp;
220
+ throw error;
221
+ }
222
+ return args;
223
+ }
224
+ function argsForFetch(getState, pathQuery2, { method = "GET", headers = {}, body = "", signal } = {}) {
225
+ method = method.toUpperCase();
226
+ const currentState = getState().superglue;
227
+ const nextHeaders = { ...headers };
228
+ nextHeaders["x-requested-with"] = "XMLHttpRequest";
229
+ nextHeaders["accept"] = "application/json";
230
+ nextHeaders["x-superglue-request"] = "true";
231
+ if (method != "GET" && method != "HEAD") {
232
+ nextHeaders["content-type"] = "application/json";
233
+ }
234
+ if (body instanceof FormData) {
235
+ delete nextHeaders["content-type"];
236
+ }
237
+ if (currentState.csrfToken) {
238
+ nextHeaders["x-csrf-token"] = currentState.csrfToken;
239
+ }
240
+ const fetchPath = new import_url_parse2.default(
241
+ formatForXHR(pathQuery2),
242
+ config.baseUrl || {},
243
+ true
244
+ );
245
+ const credentials = "same-origin";
246
+ if (!(method == "GET" || method == "HEAD")) {
247
+ nextHeaders["x-http-method-override"] = method;
248
+ method = "POST";
249
+ }
250
+ const options = {
251
+ method,
252
+ headers: nextHeaders,
253
+ body,
254
+ credentials,
255
+ signal
256
+ };
257
+ if (currentState.currentPageKey) {
258
+ const referrer = new import_url_parse2.default(
259
+ currentState.currentPageKey,
260
+ config.baseUrl || {},
261
+ false
262
+ ).href;
263
+ options.referrer = referrer;
264
+ }
265
+ if (method == "GET" || method == "HEAD") {
266
+ if (options.body instanceof FormData) {
267
+ const allData = new URLSearchParams(
268
+ options.body
269
+ );
270
+ const nextQuery = { ...fetchPath.query, ...Object.fromEntries(allData) };
271
+ fetchPath.set("query", nextQuery);
272
+ }
273
+ delete options.body;
274
+ }
275
+ return [fetchPath.toString(), options];
276
+ }
277
+ function extractJSON(rsp) {
278
+ return rsp.json().then((json) => {
279
+ return { rsp, json };
280
+ }).catch((e) => {
281
+ e.response = rsp;
282
+ throw e;
283
+ });
284
+ }
285
+ function parseResponse(prm) {
286
+ return Promise.resolve(prm).then(extractJSON).then(handleServerErrors).then(validateResponse);
287
+ }
288
+
289
+ // lib/utils/window.ts
290
+ function needsRefresh(prevAssets, newAssets) {
291
+ if (prevAssets && newAssets) {
292
+ const hasNewAssets = !newAssets.every((asset) => prevAssets.includes(asset));
293
+ return hasNewAssets;
294
+ } else {
295
+ return false;
296
+ }
297
+ }
298
+
299
+ // lib/action_creators/index.ts
300
+ var import_url_parse3 = __toESM(require("url-parse"));
301
+
302
+ // lib/actions.ts
303
+ var BEFORE_FETCH = "@@superglue/BEFORE_FETCH";
304
+ var BEFORE_VISIT = "@@superglue/BEFORE_VISIT";
305
+ var BEFORE_REMOTE = "@@superglue/BEFORE_REMOTE";
306
+ var SAVE_RESPONSE = "@@superglue/SAVE_RESPONSE";
307
+ var HANDLE_GRAFT = "@@superglue/HANDLE_GRAFT";
308
+ var SUPERGLUE_ERROR = "@@superglue/ERROR";
309
+ var GRAFTING_ERROR = "@@superglue/GRAFTING_ERROR";
310
+ var GRAFTING_SUCCESS = "@@superglue/GRAFTING_SUCCESS";
311
+ var COPY_PAGE = "@@superglue/COPY_PAGE";
312
+ var UPDATE_FRAGMENTS = "@@superglue/UPDATE_FRAGMENTS";
313
+
314
+ // lib/action_creators/requests.ts
315
+ function beforeVisit(payload) {
316
+ return {
317
+ type: BEFORE_VISIT,
318
+ payload
319
+ };
320
+ }
321
+ function beforeRemote(payload) {
322
+ return {
323
+ type: BEFORE_REMOTE,
324
+ payload
325
+ };
326
+ }
327
+ function beforeFetch(payload) {
328
+ return {
329
+ type: BEFORE_FETCH,
330
+ payload
331
+ };
332
+ }
333
+ function handleError(err) {
334
+ return {
335
+ type: SUPERGLUE_ERROR,
336
+ payload: {
337
+ message: err.message
338
+ }
339
+ };
340
+ }
341
+ function handleFetchErr(err, fetchArgs, dispatch) {
342
+ dispatch(handleError(err));
343
+ throw err;
344
+ }
345
+ function buildMeta(pageKey, page, state, rsp, fetchArgs) {
346
+ const { assets: prevAssets } = state;
347
+ const { assets: nextAssets } = page;
348
+ return {
349
+ pageKey,
350
+ page,
351
+ redirected: rsp.redirected,
352
+ rsp,
353
+ fetchArgs,
354
+ componentIdentifier: page.componentIdentifier,
355
+ needsRefresh: needsRefresh(prevAssets, nextAssets)
356
+ };
357
+ }
358
+ var remote = (path, {
359
+ method = "GET",
360
+ headers,
361
+ body,
362
+ pageKey: rawPageKey,
363
+ beforeSave = (prevPage, receivedPage) => receivedPage
364
+ } = {}) => {
365
+ path = withoutBusters(path);
366
+ rawPageKey = rawPageKey && urlToPageKey(rawPageKey);
367
+ return (dispatch, getState) => {
368
+ const fetchArgs = argsForFetch(getState, path, {
369
+ method,
370
+ headers,
371
+ body
372
+ });
373
+ if (rawPageKey === void 0) {
374
+ rawPageKey = getState().superglue.currentPageKey;
375
+ }
376
+ const pageKey = rawPageKey;
377
+ const currentPageKey = getState().superglue.currentPageKey;
378
+ dispatch(beforeRemote({ currentPageKey, fetchArgs }));
379
+ dispatch(beforeFetch({ fetchArgs }));
380
+ return fetch(...fetchArgs).then(parseResponse).then(({ rsp, json }) => {
381
+ const { superglue, pages = {} } = getState();
382
+ const meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs);
383
+ const willReplaceCurrent = pageKey == currentPageKey;
384
+ const existingId = pages[currentPageKey]?.componentIdentifier;
385
+ const receivedId = json.componentIdentifier;
386
+ if (willReplaceCurrent && !!existingId && existingId != receivedId) {
387
+ console.warn(
388
+ `You're about replace an existing page located at pages["${currentPageKey}"]
389
+ that has the componentIdentifier "${existingId}" with the contents of a
390
+ received page that has a componentIdentifier of "${receivedId}".
391
+
392
+ This can happen if you're using data-sg-remote or remote but your response
393
+ redirected to a completely different page. Since remote requests do not
394
+ navigate or change the current page component, your current page component may
395
+ receive a shape that is unexpected and cause issues with rendering.
396
+
397
+ Consider using data-sg-visit, the visit function, or redirect_back.`
398
+ );
399
+ }
400
+ const page = beforeSave(pages[pageKey], json);
401
+ return dispatch(saveAndProcessPage(pageKey, page)).then(() => meta);
402
+ }).catch((e) => handleFetchErr(e, fetchArgs, dispatch));
403
+ };
404
+ };
405
+ var lastVisitController = {
406
+ abort: () => {
407
+ }
408
+ };
409
+ var visit = (path, {
410
+ method = "GET",
411
+ headers,
412
+ body,
413
+ placeholderKey,
414
+ beforeSave = (prevPage, receivedPage) => receivedPage,
415
+ revisit = false
416
+ } = {}) => {
417
+ path = withoutBusters(path);
418
+ let pageKey = urlToPageKey(path);
419
+ return (dispatch, getState) => {
420
+ placeholderKey = placeholderKey && urlToPageKey(placeholderKey);
421
+ const hasPlaceholder = !!(placeholderKey && getState().pages[placeholderKey]);
422
+ if (placeholderKey && hasPlaceholder) {
423
+ dispatch(copyPage({ from: placeholderKey, to: pageKey }));
424
+ }
425
+ if (placeholderKey && !hasPlaceholder) {
426
+ console.warn(
427
+ `Could not find placeholder with key ${placeholderKey} in state. The props_at param will be ignored`
428
+ );
429
+ path = removePropsAt(path);
430
+ }
431
+ if (!placeholderKey && hasPropsAt(path)) {
432
+ console.warn(
433
+ `visit was called with props_at param in the path ${path}, this will be ignore unless you provide a placeholder.`
434
+ );
435
+ path = removePropsAt(path);
436
+ }
437
+ const controller = new AbortController();
438
+ const { signal } = controller;
439
+ const fetchArgs = argsForFetch(getState, path, {
440
+ headers,
441
+ body,
442
+ method,
443
+ signal
444
+ });
445
+ const currentPageKey = getState().superglue.currentPageKey;
446
+ dispatch(beforeVisit({ currentPageKey, fetchArgs }));
447
+ dispatch(beforeFetch({ fetchArgs }));
448
+ lastVisitController.abort();
449
+ lastVisitController = controller;
450
+ return fetch(...fetchArgs).then(parseResponse).then(({ rsp, json }) => {
451
+ const { superglue, pages = {} } = getState();
452
+ const meta = buildMeta(pageKey, json, superglue, rsp, fetchArgs);
453
+ const isGet = fetchArgs[1].method === "GET";
454
+ meta.suggestedAction = "push";
455
+ if (!rsp.redirected && !isGet) {
456
+ meta.suggestedAction = "replace";
457
+ }
458
+ if (revisit && isGet) {
459
+ if (rsp.redirected) {
460
+ meta.suggestedAction = "replace";
461
+ } else {
462
+ meta.suggestedAction = "none";
463
+ }
464
+ }
465
+ pageKey = urlToPageKey(rsp.url);
466
+ if (!isGet && !rsp.redirected) {
467
+ pageKey = currentPageKey;
468
+ }
469
+ const contentLocation = rsp.headers.get("content-location");
470
+ if (contentLocation) {
471
+ pageKey = urlToPageKey(contentLocation);
472
+ }
473
+ const page = beforeSave(pages[pageKey], json);
474
+ return dispatch(saveAndProcessPage(pageKey, page)).then(() => {
475
+ meta.pageKey = pageKey;
476
+ return meta;
477
+ });
478
+ }).catch((e) => handleFetchErr(e, fetchArgs, dispatch));
479
+ };
480
+ };
481
+
482
+ // lib/action_creators/index.ts
483
+ function copyPage({
484
+ from,
485
+ to
486
+ }) {
487
+ return {
488
+ type: COPY_PAGE,
489
+ payload: {
490
+ from,
491
+ to
492
+ }
493
+ };
494
+ }
495
+ function saveResponse({
496
+ pageKey,
497
+ page
498
+ }) {
499
+ pageKey = urlToPageKey(pageKey);
500
+ return {
501
+ type: SAVE_RESPONSE,
502
+ payload: {
503
+ pageKey,
504
+ page
505
+ }
506
+ };
507
+ }
508
+ function handleGraft({
509
+ pageKey,
510
+ page
511
+ }) {
512
+ pageKey = urlToPageKey(pageKey);
513
+ return {
514
+ type: HANDLE_GRAFT,
515
+ payload: {
516
+ pageKey,
517
+ page
518
+ }
519
+ };
520
+ }
521
+ function fetchDeferments(pageKey, defers = []) {
522
+ pageKey = urlToPageKey(pageKey);
523
+ return (dispatch) => {
524
+ const fetches = defers.filter(({ type }) => type === "auto").map(function({
525
+ url,
526
+ successAction = GRAFTING_SUCCESS,
527
+ failAction = GRAFTING_ERROR
528
+ }) {
529
+ const parsedUrl = new import_url_parse3.default(url, true);
530
+ const keyPath = parsedUrl.query.props_at;
531
+ return dispatch(remote(url, { pageKey })).then(() => {
532
+ dispatch({
533
+ type: successAction,
534
+ payload: {
535
+ pageKey,
536
+ keyPath
537
+ }
538
+ });
539
+ }).catch((err) => {
540
+ dispatch({
541
+ type: failAction,
542
+ payload: {
543
+ url,
544
+ err,
545
+ pageKey,
546
+ keyPath
547
+ }
548
+ });
549
+ });
550
+ });
551
+ return Promise.all(fetches);
552
+ };
553
+ }
554
+ function updateFragmentsUsing(page) {
555
+ const changedFragments = {};
556
+ page.fragments.forEach((fragment) => {
557
+ const { type, path } = fragment;
558
+ changedFragments[type] = getIn(page, path);
559
+ });
560
+ return {
561
+ type: UPDATE_FRAGMENTS,
562
+ payload: { changedFragments }
563
+ };
564
+ }
565
+ function saveAndProcessPage(pageKey, page) {
566
+ return (dispatch, getState) => {
567
+ pageKey = urlToPageKey(pageKey);
568
+ const { defers = [] } = page;
569
+ if ("action" in page) {
570
+ dispatch(handleGraft({ pageKey, page }));
571
+ } else {
572
+ dispatch(saveResponse({ pageKey, page }));
573
+ }
574
+ const hasFetch = typeof fetch != "undefined";
575
+ if (hasFetch) {
576
+ return dispatch(fetchDeferments(pageKey, defers)).then(() => {
577
+ if (page.fragments.length > 0) {
578
+ const finishedPage = getState().pages[pageKey];
579
+ dispatch(updateFragmentsUsing(finishedPage));
580
+ return Promise.resolve();
581
+ }
582
+ });
583
+ } else {
584
+ return Promise.resolve();
585
+ }
586
+ };
587
+ }
588
+ // Annotate the CommonJS export names for ESM import in node:
589
+ 0 && (module.exports = {
590
+ copyPage,
591
+ handleGraft,
592
+ remote,
593
+ saveAndProcessPage,
594
+ saveResponse,
595
+ visit
596
+ });
597
+ //# sourceMappingURL=action_creators.cjs.map