feat: docker compose maybe
This commit is contained in:
		
							
								
								
									
										7
									
								
								node_modules/svelte-hmr/runtime/hot-api-esm.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								node_modules/svelte-hmr/runtime/hot-api-esm.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
import { makeApplyHmr } from '../runtime/index.js'
 | 
			
		||||
 | 
			
		||||
export const applyHmr = makeApplyHmr(args =>
 | 
			
		||||
  Object.assign({}, args, {
 | 
			
		||||
    hot: args.m.hot,
 | 
			
		||||
  })
 | 
			
		||||
)
 | 
			
		||||
							
								
								
									
										172
									
								
								node_modules/svelte-hmr/runtime/hot-api.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										172
									
								
								node_modules/svelte-hmr/runtime/hot-api.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,172 @@
 | 
			
		||||
/* eslint-env browser */
 | 
			
		||||
 | 
			
		||||
import { createProxy, hasFatalError } from './proxy.js'
 | 
			
		||||
 | 
			
		||||
const logPrefix = '[HMR:Svelte]'
 | 
			
		||||
 | 
			
		||||
// eslint-disable-next-line no-console
 | 
			
		||||
const log = (...args) => console.log(logPrefix, ...args)
 | 
			
		||||
 | 
			
		||||
const domReload = () => {
 | 
			
		||||
  // eslint-disable-next-line no-undef
 | 
			
		||||
  const win = typeof window !== 'undefined' && window
 | 
			
		||||
  if (win && win.location && win.location.reload) {
 | 
			
		||||
    log('Reload')
 | 
			
		||||
    win.location.reload()
 | 
			
		||||
  } else {
 | 
			
		||||
    log('Full reload required')
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const replaceCss = (previousId, newId) => {
 | 
			
		||||
  if (typeof document === 'undefined') return false
 | 
			
		||||
  if (!previousId) return false
 | 
			
		||||
  if (!newId) return false
 | 
			
		||||
  // svelte-xxx-style => svelte-xxx
 | 
			
		||||
  const previousClass = previousId.slice(0, -6)
 | 
			
		||||
  const newClass = newId.slice(0, -6)
 | 
			
		||||
  // eslint-disable-next-line no-undef
 | 
			
		||||
  document.querySelectorAll('.' + previousClass).forEach(el => {
 | 
			
		||||
    el.classList.remove(previousClass)
 | 
			
		||||
    el.classList.add(newClass)
 | 
			
		||||
  })
 | 
			
		||||
  return true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const removeStylesheet = cssId => {
 | 
			
		||||
  if (cssId == null) return
 | 
			
		||||
  if (typeof document === 'undefined') return
 | 
			
		||||
  // eslint-disable-next-line no-undef
 | 
			
		||||
  const el = document.getElementById(cssId)
 | 
			
		||||
  if (el) el.remove()
 | 
			
		||||
  return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const defaultArgs = {
 | 
			
		||||
  reload: domReload,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const makeApplyHmr = transformArgs => args => {
 | 
			
		||||
  const allArgs = transformArgs({ ...defaultArgs, ...args })
 | 
			
		||||
  return applyHmr(allArgs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let needsReload = false
 | 
			
		||||
 | 
			
		||||
function applyHmr(args) {
 | 
			
		||||
  const {
 | 
			
		||||
    id,
 | 
			
		||||
    cssId,
 | 
			
		||||
    nonCssHash,
 | 
			
		||||
    reload = domReload,
 | 
			
		||||
    // normalized hot API (must conform to rollup-plugin-hot)
 | 
			
		||||
    hot,
 | 
			
		||||
    hotOptions,
 | 
			
		||||
    Component,
 | 
			
		||||
    acceptable, // some types of components are impossible to HMR correctly
 | 
			
		||||
    preserveLocalState,
 | 
			
		||||
    ProxyAdapter,
 | 
			
		||||
    emitCss,
 | 
			
		||||
  } = args
 | 
			
		||||
 | 
			
		||||
  const existing = hot.data && hot.data.record
 | 
			
		||||
 | 
			
		||||
  const canAccept = acceptable && (!existing || existing.current.canAccept)
 | 
			
		||||
 | 
			
		||||
  const r =
 | 
			
		||||
    existing ||
 | 
			
		||||
    createProxy({
 | 
			
		||||
      Adapter: ProxyAdapter,
 | 
			
		||||
      id,
 | 
			
		||||
      Component,
 | 
			
		||||
      hotOptions,
 | 
			
		||||
      canAccept,
 | 
			
		||||
      preserveLocalState,
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
  const cssOnly =
 | 
			
		||||
    hotOptions.injectCss &&
 | 
			
		||||
    existing &&
 | 
			
		||||
    nonCssHash &&
 | 
			
		||||
    existing.current.nonCssHash === nonCssHash
 | 
			
		||||
 | 
			
		||||
  r.update({
 | 
			
		||||
    Component,
 | 
			
		||||
    hotOptions,
 | 
			
		||||
    canAccept,
 | 
			
		||||
    nonCssHash,
 | 
			
		||||
    cssId,
 | 
			
		||||
    previousCssId: r.current.cssId,
 | 
			
		||||
    cssOnly,
 | 
			
		||||
    preserveLocalState,
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  hot.dispose(data => {
 | 
			
		||||
    // handle previous fatal errors
 | 
			
		||||
    if (needsReload || hasFatalError()) {
 | 
			
		||||
      if (hotOptions && hotOptions.noReload) {
 | 
			
		||||
        log('Full reload required')
 | 
			
		||||
      } else {
 | 
			
		||||
        reload()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // 2020-09-21 Snowpack master doesn't pass data as arg to dispose handler
 | 
			
		||||
    data = data || hot.data
 | 
			
		||||
 | 
			
		||||
    data.record = r
 | 
			
		||||
 | 
			
		||||
    if (!emitCss && cssId && r.current.cssId !== cssId) {
 | 
			
		||||
      if (hotOptions.cssEjectDelay) {
 | 
			
		||||
        setTimeout(() => removeStylesheet(cssId), hotOptions.cssEjectDelay)
 | 
			
		||||
      } else {
 | 
			
		||||
        removeStylesheet(cssId)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  if (canAccept) {
 | 
			
		||||
    hot.accept(async arg => {
 | 
			
		||||
      const { bubbled } = arg || {}
 | 
			
		||||
 | 
			
		||||
      // NOTE Snowpack registers accept handlers only once, so we can NOT rely
 | 
			
		||||
      // on the surrounding scope variables -- they're not the last version!
 | 
			
		||||
      const { cssId: newCssId, previousCssId } = r.current
 | 
			
		||||
      const cssChanged = newCssId !== previousCssId
 | 
			
		||||
      // ensure old style sheet has been removed by now
 | 
			
		||||
      if (!emitCss && cssChanged) removeStylesheet(previousCssId)
 | 
			
		||||
      // guard: css only change
 | 
			
		||||
      if (
 | 
			
		||||
        // NOTE bubbled is provided only by rollup-plugin-hot, and we
 | 
			
		||||
        // can't safely assume a CSS only change without it... this means we
 | 
			
		||||
        // can't support CSS only injection with Nollup or Webpack currently
 | 
			
		||||
        bubbled === false && // WARNING check false, not falsy!
 | 
			
		||||
        r.current.cssOnly &&
 | 
			
		||||
        (!cssChanged || replaceCss(previousCssId, newCssId))
 | 
			
		||||
      ) {
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const success = await r.reload()
 | 
			
		||||
 | 
			
		||||
      if (hasFatalError() || (!success && !hotOptions.optimistic)) {
 | 
			
		||||
        needsReload = true
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // well, endgame... we won't be able to render next updates, even successful,
 | 
			
		||||
  // if we don't have proxies in svelte's tree
 | 
			
		||||
  //
 | 
			
		||||
  // since we won't return the proxy and the app will expect a svelte component,
 | 
			
		||||
  // it's gonna crash... so it's best to report the real cause
 | 
			
		||||
  //
 | 
			
		||||
  // full reload required
 | 
			
		||||
  //
 | 
			
		||||
  const proxyOk = r && r.proxy
 | 
			
		||||
  if (!proxyOk) {
 | 
			
		||||
    throw new Error(`Failed to create HMR proxy for Svelte component ${id}`)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return r.proxy
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										1
									
								
								node_modules/svelte-hmr/runtime/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								node_modules/svelte-hmr/runtime/index.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
export { makeApplyHmr } from './hot-api.js'
 | 
			
		||||
							
								
								
									
										133
									
								
								node_modules/svelte-hmr/runtime/overlay.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								node_modules/svelte-hmr/runtime/overlay.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,133 @@
 | 
			
		||||
/* eslint-env browser */
 | 
			
		||||
 | 
			
		||||
const removeElement = el => el && el.parentNode && el.parentNode.removeChild(el)
 | 
			
		||||
 | 
			
		||||
const ErrorOverlay = () => {
 | 
			
		||||
  let errors = []
 | 
			
		||||
  let compileError = null
 | 
			
		||||
 | 
			
		||||
  const errorsTitle = 'Failed to init component'
 | 
			
		||||
  const compileErrorTitle = 'Failed to compile'
 | 
			
		||||
 | 
			
		||||
  const style = {
 | 
			
		||||
    section: `
 | 
			
		||||
      position: fixed;
 | 
			
		||||
      top: 0;
 | 
			
		||||
      bottom: 0;
 | 
			
		||||
      left: 0;
 | 
			
		||||
      right: 0;
 | 
			
		||||
      padding: 32px;
 | 
			
		||||
      background: rgba(0, 0, 0, .85);
 | 
			
		||||
      font-family: Menlo, Consolas, monospace;
 | 
			
		||||
      font-size: large;
 | 
			
		||||
      color: rgb(232, 232, 232);
 | 
			
		||||
      overflow: auto;
 | 
			
		||||
      z-index: 2147483647;
 | 
			
		||||
    `,
 | 
			
		||||
    h1: `
 | 
			
		||||
      margin-top: 0;
 | 
			
		||||
      color: #E36049;
 | 
			
		||||
      font-size: large;
 | 
			
		||||
      font-weight: normal;
 | 
			
		||||
    `,
 | 
			
		||||
    h2: `
 | 
			
		||||
      margin: 32px 0 0;
 | 
			
		||||
      font-size: large;
 | 
			
		||||
      font-weight: normal;
 | 
			
		||||
    `,
 | 
			
		||||
    pre: ``,
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const createOverlay = () => {
 | 
			
		||||
    const h1 = document.createElement('h1')
 | 
			
		||||
    h1.style = style.h1
 | 
			
		||||
    const section = document.createElement('section')
 | 
			
		||||
    section.appendChild(h1)
 | 
			
		||||
    section.style = style.section
 | 
			
		||||
    const body = document.createElement('div')
 | 
			
		||||
    section.appendChild(body)
 | 
			
		||||
    return { h1, el: section, body }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const setTitle = title => {
 | 
			
		||||
    overlay.h1.textContent = title
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const show = () => {
 | 
			
		||||
    const { el } = overlay
 | 
			
		||||
    if (!el.parentNode) {
 | 
			
		||||
      const target = document.body
 | 
			
		||||
      target.appendChild(overlay.el)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const hide = () => {
 | 
			
		||||
    const { el } = overlay
 | 
			
		||||
    if (el.parentNode) {
 | 
			
		||||
      overlay.el.remove()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const update = () => {
 | 
			
		||||
    if (compileError) {
 | 
			
		||||
      overlay.body.innerHTML = ''
 | 
			
		||||
      setTitle(compileErrorTitle)
 | 
			
		||||
      const errorEl = renderError(compileError)
 | 
			
		||||
      overlay.body.appendChild(errorEl)
 | 
			
		||||
      show()
 | 
			
		||||
    } else if (errors.length > 0) {
 | 
			
		||||
      overlay.body.innerHTML = ''
 | 
			
		||||
      setTitle(errorsTitle)
 | 
			
		||||
      errors.forEach(({ title, message }) => {
 | 
			
		||||
        const errorEl = renderError(message, title)
 | 
			
		||||
        overlay.body.appendChild(errorEl)
 | 
			
		||||
      })
 | 
			
		||||
      show()
 | 
			
		||||
    } else {
 | 
			
		||||
      hide()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const renderError = (message, title) => {
 | 
			
		||||
    const div = document.createElement('div')
 | 
			
		||||
    if (title) {
 | 
			
		||||
      const h2 = document.createElement('h2')
 | 
			
		||||
      h2.textContent = title
 | 
			
		||||
      h2.style = style.h2
 | 
			
		||||
      div.appendChild(h2)
 | 
			
		||||
    }
 | 
			
		||||
    const pre = document.createElement('pre')
 | 
			
		||||
    pre.textContent = message
 | 
			
		||||
    div.appendChild(pre)
 | 
			
		||||
    return div
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const addError = (error, title) => {
 | 
			
		||||
    const message = (error && error.stack) || error
 | 
			
		||||
    errors.push({ title, message })
 | 
			
		||||
    update()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const clearErrors = () => {
 | 
			
		||||
    errors.forEach(({ element }) => {
 | 
			
		||||
      removeElement(element)
 | 
			
		||||
    })
 | 
			
		||||
    errors = []
 | 
			
		||||
    update()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const setCompileError = message => {
 | 
			
		||||
    compileError = message
 | 
			
		||||
    update()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const overlay = createOverlay()
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    addError,
 | 
			
		||||
    clearErrors,
 | 
			
		||||
    setCompileError,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default ErrorOverlay
 | 
			
		||||
							
								
								
									
										105
									
								
								node_modules/svelte-hmr/runtime/proxy-adapter-dom.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								node_modules/svelte-hmr/runtime/proxy-adapter-dom.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
/* global window, document */
 | 
			
		||||
import * as svelteInternal from 'svelte/internal'
 | 
			
		||||
// NOTE from 3.38.3 (or so), insert was carrying the hydration logic, that must
 | 
			
		||||
// be used because DOM elements are reused more (and so insertion points are not
 | 
			
		||||
// necessarily added in order); then in 3.40 the logic was moved to
 | 
			
		||||
// insert_hydration, which is the one we must use for HMR
 | 
			
		||||
const svelteInsert = svelteInternal.insert_hydration || svelteInternal.insert
 | 
			
		||||
if (!svelteInsert) {
 | 
			
		||||
  throw new Error(
 | 
			
		||||
    'failed to find insert_hydration and insert in svelte/internal'
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
import ErrorOverlay from './overlay.js'
 | 
			
		||||
 | 
			
		||||
const removeElement = el => el && el.parentNode && el.parentNode.removeChild(el)
 | 
			
		||||
 | 
			
		||||
export const adapter = class ProxyAdapterDom {
 | 
			
		||||
  constructor(instance) {
 | 
			
		||||
    this.instance = instance
 | 
			
		||||
    this.insertionPoint = null
 | 
			
		||||
 | 
			
		||||
    this.afterMount = this.afterMount.bind(this)
 | 
			
		||||
    this.rerender = this.rerender.bind(this)
 | 
			
		||||
 | 
			
		||||
    this._noOverlay = !!instance.hotOptions.noOverlay
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // NOTE overlay is only created before being actually shown to help test
 | 
			
		||||
  // runner (it won't have to account for error overlay when running assertions
 | 
			
		||||
  // about the contents of the rendered page)
 | 
			
		||||
  static getErrorOverlay(noCreate = false) {
 | 
			
		||||
    if (!noCreate && !this.errorOverlay) {
 | 
			
		||||
      this.errorOverlay = ErrorOverlay()
 | 
			
		||||
    }
 | 
			
		||||
    return this.errorOverlay
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // TODO this is probably unused now: remove in next breaking release
 | 
			
		||||
  static renderCompileError(message) {
 | 
			
		||||
    const noCreate = !message
 | 
			
		||||
    const overlay = this.getErrorOverlay(noCreate)
 | 
			
		||||
    if (!overlay) return
 | 
			
		||||
    overlay.setCompileError(message)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  dispose() {
 | 
			
		||||
    // Component is being destroyed, detaching is not optional in Svelte3's
 | 
			
		||||
    // component API, so we can dispose of the insertion point in every case.
 | 
			
		||||
    if (this.insertionPoint) {
 | 
			
		||||
      removeElement(this.insertionPoint)
 | 
			
		||||
      this.insertionPoint = null
 | 
			
		||||
    }
 | 
			
		||||
    this.clearError()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // NOTE afterMount CAN be called multiple times (e.g. keyed list)
 | 
			
		||||
  afterMount(target, anchor) {
 | 
			
		||||
    const {
 | 
			
		||||
      instance: { debugName },
 | 
			
		||||
    } = this
 | 
			
		||||
    if (!this.insertionPoint) {
 | 
			
		||||
      this.insertionPoint = document.createComment(debugName)
 | 
			
		||||
    }
 | 
			
		||||
    svelteInsert(target, this.insertionPoint, anchor)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  rerender() {
 | 
			
		||||
    this.clearError()
 | 
			
		||||
    const {
 | 
			
		||||
      instance: { refreshComponent },
 | 
			
		||||
      insertionPoint,
 | 
			
		||||
    } = this
 | 
			
		||||
    if (!insertionPoint) {
 | 
			
		||||
      throw new Error('Cannot rerender: missing insertion point')
 | 
			
		||||
    }
 | 
			
		||||
    refreshComponent(insertionPoint.parentNode, insertionPoint)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  renderError(err) {
 | 
			
		||||
    if (this._noOverlay) return
 | 
			
		||||
    const {
 | 
			
		||||
      instance: { debugName },
 | 
			
		||||
    } = this
 | 
			
		||||
    const title = debugName || err.moduleName || 'Error'
 | 
			
		||||
    this.constructor.getErrorOverlay().addError(err, title)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  clearError() {
 | 
			
		||||
    if (this._noOverlay) return
 | 
			
		||||
    const overlay = this.constructor.getErrorOverlay(true)
 | 
			
		||||
    if (!overlay) return
 | 
			
		||||
    overlay.clearErrors()
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// TODO this is probably unused now: remove in next breaking release
 | 
			
		||||
if (typeof window !== 'undefined') {
 | 
			
		||||
  window.__SVELTE_HMR_ADAPTER = adapter
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// mitigate situation with Snowpack remote source pulling latest of runtime,
 | 
			
		||||
// but using previous version of the Node code transform in the plugin
 | 
			
		||||
// see: https://github.com/rixo/svelte-hmr/issues/27
 | 
			
		||||
export default adapter
 | 
			
		||||
							
								
								
									
										427
									
								
								node_modules/svelte-hmr/runtime/proxy.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										427
									
								
								node_modules/svelte-hmr/runtime/proxy.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,427 @@
 | 
			
		||||
/* eslint-env browser */
 | 
			
		||||
/**
 | 
			
		||||
 * The HMR proxy is a component-like object whose task is to sit in the
 | 
			
		||||
 * component tree in place of the proxied component, and rerender each
 | 
			
		||||
 * successive versions of said component.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { createProxiedComponent } from './svelte-hooks.js'
 | 
			
		||||
 | 
			
		||||
const handledMethods = ['constructor', '$destroy']
 | 
			
		||||
const forwardedMethods = ['$set', '$on']
 | 
			
		||||
 | 
			
		||||
const logError = (msg, err) => {
 | 
			
		||||
  // eslint-disable-next-line no-console
 | 
			
		||||
  console.error('[HMR][Svelte]', msg)
 | 
			
		||||
  if (err) {
 | 
			
		||||
    // NOTE avoid too much wrapping around user errors
 | 
			
		||||
    // eslint-disable-next-line no-console
 | 
			
		||||
    console.error(err)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const posixify = file => file.replace(/[/\\]/g, '/')
 | 
			
		||||
 | 
			
		||||
const getBaseName = id =>
 | 
			
		||||
  id
 | 
			
		||||
    .split('/')
 | 
			
		||||
    .pop()
 | 
			
		||||
    .split('.')
 | 
			
		||||
    .slice(0, -1)
 | 
			
		||||
    .join('.')
 | 
			
		||||
 | 
			
		||||
const capitalize = str => str[0].toUpperCase() + str.slice(1)
 | 
			
		||||
 | 
			
		||||
const getFriendlyName = id => capitalize(getBaseName(posixify(id)))
 | 
			
		||||
 | 
			
		||||
const getDebugName = id => `<${getFriendlyName(id)}>`
 | 
			
		||||
 | 
			
		||||
const relayCalls = (getTarget, names, dest = {}) => {
 | 
			
		||||
  for (const key of names) {
 | 
			
		||||
    dest[key] = function(...args) {
 | 
			
		||||
      const target = getTarget()
 | 
			
		||||
      if (!target) {
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      return target[key] && target[key].call(this, ...args)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return dest
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const isInternal = key => key !== '$$' && key.slice(0, 2) === '$$'
 | 
			
		||||
 | 
			
		||||
// This is intented as a somewhat generic / prospective fix to the situation
 | 
			
		||||
// that arised with the introduction of $$set in Svelte 3.24.1 -- trying to
 | 
			
		||||
// avoid giving full knowledge (like its name) of this implementation detail
 | 
			
		||||
// to the proxy. The $$set method can be present or not on the component, and
 | 
			
		||||
// its presence impacts the behaviour (but with HMR it will be tested if it is
 | 
			
		||||
// present _on the proxy_). So the idea here is to expose exactly the same $$
 | 
			
		||||
// props as the current version of the component and, for those that are
 | 
			
		||||
// functions, proxy the calls to the current component.
 | 
			
		||||
const relayInternalMethods = (proxy, cmp) => {
 | 
			
		||||
  // delete any previously added $$ prop
 | 
			
		||||
  Object.keys(proxy)
 | 
			
		||||
    .filter(isInternal)
 | 
			
		||||
    .forEach(key => {
 | 
			
		||||
      delete proxy[key]
 | 
			
		||||
    })
 | 
			
		||||
  // guard: no component
 | 
			
		||||
  if (!cmp) return
 | 
			
		||||
  // proxy current $$ props to the actual component
 | 
			
		||||
  Object.keys(cmp)
 | 
			
		||||
    .filter(isInternal)
 | 
			
		||||
    .forEach(key => {
 | 
			
		||||
      Object.defineProperty(proxy, key, {
 | 
			
		||||
        configurable: true,
 | 
			
		||||
        get() {
 | 
			
		||||
          const value = cmp[key]
 | 
			
		||||
          if (typeof value !== 'function') return value
 | 
			
		||||
          return (
 | 
			
		||||
            value &&
 | 
			
		||||
            function(...args) {
 | 
			
		||||
              return value.apply(this, args)
 | 
			
		||||
            }
 | 
			
		||||
          )
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
    })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// proxy custom methods
 | 
			
		||||
const copyComponentProperties = (proxy, cmp, previous) => {
 | 
			
		||||
  if (previous) {
 | 
			
		||||
    previous.forEach(prop => {
 | 
			
		||||
      delete proxy[prop]
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const props = Object.getOwnPropertyNames(Object.getPrototypeOf(cmp))
 | 
			
		||||
  const wrappedProps = props.filter(prop => {
 | 
			
		||||
    if (!handledMethods.includes(prop) && !forwardedMethods.includes(prop)) {
 | 
			
		||||
      Object.defineProperty(proxy, prop, {
 | 
			
		||||
        configurable: true,
 | 
			
		||||
        get() {
 | 
			
		||||
          return cmp[prop]
 | 
			
		||||
        },
 | 
			
		||||
        set(value) {
 | 
			
		||||
          // we're changing it on the real component first to see what it
 | 
			
		||||
          // gives... if it throws an error, we want to throw the same error in
 | 
			
		||||
          // order to most closely follow non-hmr behaviour.
 | 
			
		||||
          cmp[prop] = value
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
      return true
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  return wrappedProps
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// everything in the constructor!
 | 
			
		||||
//
 | 
			
		||||
// so we don't polute the component class with new members
 | 
			
		||||
//
 | 
			
		||||
class ProxyComponent {
 | 
			
		||||
  constructor(
 | 
			
		||||
    {
 | 
			
		||||
      Adapter,
 | 
			
		||||
      id,
 | 
			
		||||
      debugName,
 | 
			
		||||
      current, // { Component, hotOptions: { preserveLocalState, ... } }
 | 
			
		||||
      register,
 | 
			
		||||
    },
 | 
			
		||||
    options // { target, anchor, ... }
 | 
			
		||||
  ) {
 | 
			
		||||
    let cmp
 | 
			
		||||
    let disposed = false
 | 
			
		||||
    let lastError = null
 | 
			
		||||
 | 
			
		||||
    const setComponent = _cmp => {
 | 
			
		||||
      cmp = _cmp
 | 
			
		||||
      relayInternalMethods(this, cmp)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const getComponent = () => cmp
 | 
			
		||||
 | 
			
		||||
    const destroyComponent = () => {
 | 
			
		||||
      // destroyComponent is tolerant (don't crash on no cmp) because it
 | 
			
		||||
      // is possible that reload/rerender is called after a previous
 | 
			
		||||
      // createComponent has failed (hence we have a proxy, but no cmp)
 | 
			
		||||
      if (cmp) {
 | 
			
		||||
        cmp.$destroy()
 | 
			
		||||
        setComponent(null)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const refreshComponent = (target, anchor, conservativeDestroy) => {
 | 
			
		||||
      if (lastError) {
 | 
			
		||||
        lastError = null
 | 
			
		||||
        adapter.rerender()
 | 
			
		||||
      } else {
 | 
			
		||||
        try {
 | 
			
		||||
          const replaceOptions = {
 | 
			
		||||
            target,
 | 
			
		||||
            anchor,
 | 
			
		||||
            preserveLocalState: current.preserveLocalState,
 | 
			
		||||
          }
 | 
			
		||||
          if (conservativeDestroy) {
 | 
			
		||||
            replaceOptions.conservativeDestroy = true
 | 
			
		||||
          }
 | 
			
		||||
          cmp.$replace(current.Component, replaceOptions)
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
          setError(err, target, anchor)
 | 
			
		||||
          if (
 | 
			
		||||
            !current.hotOptions.optimistic ||
 | 
			
		||||
            // non acceptable components (that is components that have to defer
 | 
			
		||||
            // to their parent for rerender -- e.g. accessors, named exports)
 | 
			
		||||
            // are most tricky, and they havent been considered when most of the
 | 
			
		||||
            // code has been written... as a result, they are especially tricky
 | 
			
		||||
            // to deal with, it's better to consider any error with them to be
 | 
			
		||||
            // fatal to avoid odities
 | 
			
		||||
            !current.canAccept ||
 | 
			
		||||
            (err && err.hmrFatal)
 | 
			
		||||
          ) {
 | 
			
		||||
            throw err
 | 
			
		||||
          } else {
 | 
			
		||||
            // const errString = String((err && err.stack) || err)
 | 
			
		||||
            logError(`Error during component init: ${debugName}`, err)
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const setError = err => {
 | 
			
		||||
      lastError = err
 | 
			
		||||
      adapter.renderError(err)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const instance = {
 | 
			
		||||
      hotOptions: current.hotOptions,
 | 
			
		||||
      proxy: this,
 | 
			
		||||
      id,
 | 
			
		||||
      debugName,
 | 
			
		||||
      refreshComponent,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const adapter = new Adapter(instance)
 | 
			
		||||
 | 
			
		||||
    const { afterMount, rerender } = adapter
 | 
			
		||||
 | 
			
		||||
    // $destroy is not called when a child component is disposed, so we
 | 
			
		||||
    // need to hook from fragment.
 | 
			
		||||
    const onDestroy = () => {
 | 
			
		||||
      // NOTE do NOT call $destroy on the cmp from here; the cmp is already
 | 
			
		||||
      //   dead, this would not work
 | 
			
		||||
      if (!disposed) {
 | 
			
		||||
        disposed = true
 | 
			
		||||
        adapter.dispose()
 | 
			
		||||
        unregister()
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ---- register proxy instance ----
 | 
			
		||||
 | 
			
		||||
    const unregister = register(rerender)
 | 
			
		||||
 | 
			
		||||
    // ---- augmented methods ----
 | 
			
		||||
 | 
			
		||||
    this.$destroy = () => {
 | 
			
		||||
      destroyComponent()
 | 
			
		||||
      onDestroy()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // ---- forwarded methods ----
 | 
			
		||||
 | 
			
		||||
    relayCalls(getComponent, forwardedMethods, this)
 | 
			
		||||
 | 
			
		||||
    // ---- create & mount target component instance ---
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      let lastProperties
 | 
			
		||||
      createProxiedComponent(current.Component, options, {
 | 
			
		||||
        allowLiveBinding: current.hotOptions.allowLiveBinding,
 | 
			
		||||
        onDestroy,
 | 
			
		||||
        onMount: afterMount,
 | 
			
		||||
        onInstance: comp => {
 | 
			
		||||
          setComponent(comp)
 | 
			
		||||
          // WARNING the proxy MUST use the same $$ object as its component
 | 
			
		||||
          // instance, because a lot of wiring happens during component
 | 
			
		||||
          // initialisation... lots of references to $$ and $$.fragment have
 | 
			
		||||
          // already been distributed around when the component constructor
 | 
			
		||||
          // returns, before we have a chance to wrap them (and so we can't
 | 
			
		||||
          // wrap them no more, because existing references would become
 | 
			
		||||
          // invalid)
 | 
			
		||||
          this.$$ = comp.$$
 | 
			
		||||
          lastProperties = copyComponentProperties(this, comp, lastProperties)
 | 
			
		||||
        },
 | 
			
		||||
      })
 | 
			
		||||
    } catch (err) {
 | 
			
		||||
      const { target, anchor } = options
 | 
			
		||||
      setError(err, target, anchor)
 | 
			
		||||
      throw err
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const syncStatics = (component, proxy, previousKeys) => {
 | 
			
		||||
  // remove previously copied keys
 | 
			
		||||
  if (previousKeys) {
 | 
			
		||||
    for (const key of previousKeys) {
 | 
			
		||||
      delete proxy[key]
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // forward static properties and methods
 | 
			
		||||
  const keys = []
 | 
			
		||||
  for (const key in component) {
 | 
			
		||||
    keys.push(key)
 | 
			
		||||
    proxy[key] = component[key]
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return keys
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const globalListeners = {}
 | 
			
		||||
 | 
			
		||||
const onGlobal = (event, fn) => {
 | 
			
		||||
  event = event.toLowerCase()
 | 
			
		||||
  if (!globalListeners[event]) globalListeners[event] = []
 | 
			
		||||
  globalListeners[event].push(fn)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const fireGlobal = (event, ...args) => {
 | 
			
		||||
  const listeners = globalListeners[event]
 | 
			
		||||
  if (!listeners) return
 | 
			
		||||
  for (const fn of listeners) {
 | 
			
		||||
    fn(...args)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const fireBeforeUpdate = () => fireGlobal('beforeupdate')
 | 
			
		||||
 | 
			
		||||
const fireAfterUpdate = () => fireGlobal('afterupdate')
 | 
			
		||||
 | 
			
		||||
if (typeof window !== 'undefined') {
 | 
			
		||||
  window.__SVELTE_HMR = {
 | 
			
		||||
    on: onGlobal,
 | 
			
		||||
  }
 | 
			
		||||
  window.dispatchEvent(new CustomEvent('svelte-hmr:ready'))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
let fatalError = false
 | 
			
		||||
 | 
			
		||||
export const hasFatalError = () => fatalError
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Creates a HMR proxy and its associated `reload` function that pushes a new
 | 
			
		||||
 * version to all existing instances of the component.
 | 
			
		||||
 */
 | 
			
		||||
export function createProxy({
 | 
			
		||||
  Adapter,
 | 
			
		||||
  id,
 | 
			
		||||
  Component,
 | 
			
		||||
  hotOptions,
 | 
			
		||||
  canAccept,
 | 
			
		||||
  preserveLocalState,
 | 
			
		||||
}) {
 | 
			
		||||
  const debugName = getDebugName(id)
 | 
			
		||||
  const instances = []
 | 
			
		||||
 | 
			
		||||
  // current object will be updated, proxy instances will keep a ref
 | 
			
		||||
  const current = {
 | 
			
		||||
    Component,
 | 
			
		||||
    hotOptions,
 | 
			
		||||
    canAccept,
 | 
			
		||||
    preserveLocalState,
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const name = `Proxy${debugName}`
 | 
			
		||||
 | 
			
		||||
  // this trick gives the dynamic name Proxy<MyComponent> to the concrete
 | 
			
		||||
  // proxy class... unfortunately, this doesn't shows in dev tools, but
 | 
			
		||||
  // it stills allow to inspect cmp.constructor.name to confirm an instance
 | 
			
		||||
  // is a proxy
 | 
			
		||||
  const proxy = {
 | 
			
		||||
    [name]: class extends ProxyComponent {
 | 
			
		||||
      constructor(options) {
 | 
			
		||||
        try {
 | 
			
		||||
          super(
 | 
			
		||||
            {
 | 
			
		||||
              Adapter,
 | 
			
		||||
              id,
 | 
			
		||||
              debugName,
 | 
			
		||||
              current,
 | 
			
		||||
              register: rerender => {
 | 
			
		||||
                instances.push(rerender)
 | 
			
		||||
                const unregister = () => {
 | 
			
		||||
                  const i = instances.indexOf(rerender)
 | 
			
		||||
                  instances.splice(i, 1)
 | 
			
		||||
                }
 | 
			
		||||
                return unregister
 | 
			
		||||
              },
 | 
			
		||||
            },
 | 
			
		||||
            options
 | 
			
		||||
          )
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
          // If we fail to create a proxy instance, any instance, that means
 | 
			
		||||
          // that we won't be able to fix this instance when it is updated.
 | 
			
		||||
          // Recovering to normal state will be impossible. HMR's dead.
 | 
			
		||||
          //
 | 
			
		||||
          // Fatal error will trigger a full reload on next update (reloading
 | 
			
		||||
          // right now is kinda pointless since buggy code still exists).
 | 
			
		||||
          //
 | 
			
		||||
          // NOTE Only report first error to avoid too much polution -- following
 | 
			
		||||
          // errors are probably caused by the first one, or they will show up
 | 
			
		||||
          // in turn when the first one is fixed ¯\_(ツ)_/¯
 | 
			
		||||
          //
 | 
			
		||||
          if (!fatalError) {
 | 
			
		||||
            fatalError = true
 | 
			
		||||
            logError(
 | 
			
		||||
              `Unrecoverable HMR error in ${debugName}: ` +
 | 
			
		||||
                `next update will trigger a full reload`
 | 
			
		||||
            )
 | 
			
		||||
          }
 | 
			
		||||
          throw err
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  }[name]
 | 
			
		||||
 | 
			
		||||
  // initialize static members
 | 
			
		||||
  let previousStatics = syncStatics(current.Component, proxy)
 | 
			
		||||
 | 
			
		||||
  const update = newState => Object.assign(current, newState)
 | 
			
		||||
 | 
			
		||||
  // reload all existing instances of this component
 | 
			
		||||
  const reload = () => {
 | 
			
		||||
    fireBeforeUpdate()
 | 
			
		||||
 | 
			
		||||
    // copy statics before doing anything because a static prop/method
 | 
			
		||||
    // could be used somewhere in the create/render call
 | 
			
		||||
    previousStatics = syncStatics(current.Component, proxy, previousStatics)
 | 
			
		||||
 | 
			
		||||
    const errors = []
 | 
			
		||||
 | 
			
		||||
    instances.forEach(rerender => {
 | 
			
		||||
      try {
 | 
			
		||||
        rerender()
 | 
			
		||||
      } catch (err) {
 | 
			
		||||
        logError(`Failed to rerender ${debugName}`, err)
 | 
			
		||||
        errors.push(err)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    if (errors.length > 0) {
 | 
			
		||||
      return false
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fireAfterUpdate()
 | 
			
		||||
 | 
			
		||||
    return true
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const hasFatalError = () => fatalError
 | 
			
		||||
 | 
			
		||||
  return { id, proxy, update, reload, hasFatalError, current }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										347
									
								
								node_modules/svelte-hmr/runtime/svelte-hooks.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										347
									
								
								node_modules/svelte-hmr/runtime/svelte-hooks.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,347 @@
 | 
			
		||||
/**
 | 
			
		||||
 * Emulates forthcoming HMR hooks in Svelte.
 | 
			
		||||
 *
 | 
			
		||||
 * All references to private component state ($$) are now isolated in this
 | 
			
		||||
 * module.
 | 
			
		||||
 */
 | 
			
		||||
import {
 | 
			
		||||
  current_component,
 | 
			
		||||
  get_current_component,
 | 
			
		||||
  set_current_component,
 | 
			
		||||
} from 'svelte/internal'
 | 
			
		||||
 | 
			
		||||
const captureState = cmp => {
 | 
			
		||||
  // sanity check: propper behaviour here is to crash noisily so that
 | 
			
		||||
  // user knows that they're looking at something broken
 | 
			
		||||
  if (!cmp) {
 | 
			
		||||
    throw new Error('Missing component')
 | 
			
		||||
  }
 | 
			
		||||
  if (!cmp.$$) {
 | 
			
		||||
    throw new Error('Invalid component')
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const {
 | 
			
		||||
    $$: { callbacks, bound, ctx, props },
 | 
			
		||||
  } = cmp
 | 
			
		||||
 | 
			
		||||
  const state = cmp.$capture_state()
 | 
			
		||||
 | 
			
		||||
  // capturing current value of props (or we'll recreate the component with the
 | 
			
		||||
  // initial prop values, that may have changed -- and would not be reflected in
 | 
			
		||||
  // options.props)
 | 
			
		||||
  const hmr_props_values = {}
 | 
			
		||||
  Object.keys(cmp.$$.props).forEach(prop => {
 | 
			
		||||
    hmr_props_values[prop] = ctx[props[prop]]
 | 
			
		||||
  })
 | 
			
		||||
 | 
			
		||||
  return {
 | 
			
		||||
    ctx,
 | 
			
		||||
    props,
 | 
			
		||||
    callbacks,
 | 
			
		||||
    bound,
 | 
			
		||||
    state,
 | 
			
		||||
    hmr_props_values,
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// remapping all existing bindings (including hmr_future_foo ones) to the
 | 
			
		||||
// new version's props indexes, and refresh them with the new value from
 | 
			
		||||
// context
 | 
			
		||||
const restoreBound = (cmp, restore) => {
 | 
			
		||||
  // reverse prop:ctxIndex in $$.props to ctxIndex:prop
 | 
			
		||||
  //
 | 
			
		||||
  // ctxIndex can be either a regular index in $$.ctx or a hmr_future_ prop
 | 
			
		||||
  //
 | 
			
		||||
  const propsByIndex = {}
 | 
			
		||||
  for (const [name, i] of Object.entries(restore.props)) {
 | 
			
		||||
    propsByIndex[i] = name
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // NOTE $$.bound cannot change in the HMR lifetime of a component, because
 | 
			
		||||
  //      if bindings changes, that means the parent component has changed,
 | 
			
		||||
  //      which means the child (current) component will be wholly recreated
 | 
			
		||||
  for (const [oldIndex, updateBinding] of Object.entries(restore.bound)) {
 | 
			
		||||
    // can be either regular prop, or future_hmr_ prop
 | 
			
		||||
    const propName = propsByIndex[oldIndex]
 | 
			
		||||
 | 
			
		||||
    // this should never happen if remembering of future props is enabled...
 | 
			
		||||
    // in any case, there's nothing we can do about it if we have lost prop
 | 
			
		||||
    // name knowledge at this point
 | 
			
		||||
    if (propName == null) continue
 | 
			
		||||
 | 
			
		||||
    // NOTE $$.props[propName] also propagates knowledge of a possible
 | 
			
		||||
    //      future prop to the new $$.props (via $$.props being a Proxy)
 | 
			
		||||
    const newIndex = cmp.$$.props[propName]
 | 
			
		||||
    cmp.$$.bound[newIndex] = updateBinding
 | 
			
		||||
 | 
			
		||||
    // NOTE if the prop doesn't exist or doesn't exist anymore in the new
 | 
			
		||||
    //      version of the component, clearing the binding is the expected
 | 
			
		||||
    //      behaviour (since that's what would happen in non HMR code)
 | 
			
		||||
    const newValue = cmp.$$.ctx[newIndex]
 | 
			
		||||
    updateBinding(newValue)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// restoreState
 | 
			
		||||
//
 | 
			
		||||
// It is too late to restore context at this point because component instance
 | 
			
		||||
// function has already been called (and so context has already been read).
 | 
			
		||||
// Instead, we rely on setting current_component to the same value it has when
 | 
			
		||||
// the component was first rendered -- which fix support for context, and is
 | 
			
		||||
// also generally more respectful of normal operation.
 | 
			
		||||
//
 | 
			
		||||
const restoreState = (cmp, restore) => {
 | 
			
		||||
  if (!restore) return
 | 
			
		||||
 | 
			
		||||
  if (restore.callbacks) {
 | 
			
		||||
    cmp.$$.callbacks = restore.callbacks
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (restore.bound) {
 | 
			
		||||
    restoreBound(cmp, restore)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // props, props.$$slots are restored at component creation (works
 | 
			
		||||
  // better -- well, at all actually)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const get_current_component_safe = () => {
 | 
			
		||||
  // NOTE relying on dynamic bindings (current_component) makes us dependent on
 | 
			
		||||
  // bundler config (and apparently it does not work in demo-svelte-nollup)
 | 
			
		||||
  try {
 | 
			
		||||
    // unfortunately, unlike current_component, get_current_component() can
 | 
			
		||||
    // crash in the normal path (when there is really no parent)
 | 
			
		||||
    return get_current_component()
 | 
			
		||||
  } catch (err) {
 | 
			
		||||
    // ... so we need to consider that this error means that there is no parent
 | 
			
		||||
    //
 | 
			
		||||
    // that makes us tightly coupled to the error message but, at least, we
 | 
			
		||||
    // won't mute an unexpected error, which is quite a horrible thing to do
 | 
			
		||||
    if (err.message === 'Function called outside component initialization') {
 | 
			
		||||
      // who knows...
 | 
			
		||||
      return current_component
 | 
			
		||||
    } else {
 | 
			
		||||
      throw err
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const createProxiedComponent = (
 | 
			
		||||
  Component,
 | 
			
		||||
  initialOptions,
 | 
			
		||||
  { allowLiveBinding, onInstance, onMount, onDestroy }
 | 
			
		||||
) => {
 | 
			
		||||
  let cmp
 | 
			
		||||
  let options = initialOptions
 | 
			
		||||
 | 
			
		||||
  const isCurrent = _cmp => cmp === _cmp
 | 
			
		||||
 | 
			
		||||
  const assignOptions = (target, anchor, restore, preserveLocalState) => {
 | 
			
		||||
    const props = Object.assign({}, options.props)
 | 
			
		||||
 | 
			
		||||
    // Filtering props to avoid "unexpected prop" warning
 | 
			
		||||
    // NOTE this is based on props present in initial options, but it should
 | 
			
		||||
    //      always works, because props that are passed from the parent can't
 | 
			
		||||
    //      change without a code change to the parent itself -- hence, the
 | 
			
		||||
    //      child component will be fully recreated, and initial options should
 | 
			
		||||
    //      always represent props that are currnetly passed by the parent
 | 
			
		||||
    if (options.props && restore.hmr_props_values) {
 | 
			
		||||
      for (const prop of Object.keys(options.props)) {
 | 
			
		||||
        if (restore.hmr_props_values.hasOwnProperty(prop)) {
 | 
			
		||||
          props[prop] = restore.hmr_props_values[prop]
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (preserveLocalState && restore.state) {
 | 
			
		||||
      if (Array.isArray(preserveLocalState)) {
 | 
			
		||||
        // form ['a', 'b'] => preserve only 'a' and 'b'
 | 
			
		||||
        props.$$inject = {}
 | 
			
		||||
        for (const key of preserveLocalState) {
 | 
			
		||||
          props.$$inject[key] = restore.state[key]
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        props.$$inject = restore.state
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      delete props.$$inject
 | 
			
		||||
    }
 | 
			
		||||
    options = Object.assign({}, initialOptions, {
 | 
			
		||||
      target,
 | 
			
		||||
      anchor,
 | 
			
		||||
      props,
 | 
			
		||||
      hydrate: false,
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Preserving knowledge of "future props" -- very hackish version (maybe
 | 
			
		||||
  // there should be an option to opt out of this)
 | 
			
		||||
  //
 | 
			
		||||
  // The use case is bind:something where something doesn't exist yet in the
 | 
			
		||||
  // target component, but comes to exist later, after a HMR update.
 | 
			
		||||
  //
 | 
			
		||||
  // If Svelte can't map a prop in the current version of the component, it
 | 
			
		||||
  // will just completely discard it:
 | 
			
		||||
  // https://github.com/sveltejs/svelte/blob/1632bca34e4803d6b0e0b0abd652ab5968181860/src/runtime/internal/Component.ts#L46
 | 
			
		||||
  //
 | 
			
		||||
  const rememberFutureProps = cmp => {
 | 
			
		||||
    if (typeof Proxy === 'undefined') return
 | 
			
		||||
 | 
			
		||||
    cmp.$$.props = new Proxy(cmp.$$.props, {
 | 
			
		||||
      get(target, name) {
 | 
			
		||||
        if (target[name] === undefined) {
 | 
			
		||||
          target[name] = 'hmr_future_' + name
 | 
			
		||||
        }
 | 
			
		||||
        return target[name]
 | 
			
		||||
      },
 | 
			
		||||
      set(target, name, value) {
 | 
			
		||||
        target[name] = value
 | 
			
		||||
      },
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const instrument = targetCmp => {
 | 
			
		||||
    const createComponent = (Component, restore, previousCmp) => {
 | 
			
		||||
      set_current_component(parentComponent || previousCmp)
 | 
			
		||||
      const comp = new Component(options)
 | 
			
		||||
      // NOTE must be instrumented before restoreState, because restoring
 | 
			
		||||
      // bindings relies on hacked $$.props
 | 
			
		||||
      instrument(comp)
 | 
			
		||||
      restoreState(comp, restore)
 | 
			
		||||
      return comp
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rememberFutureProps(targetCmp)
 | 
			
		||||
 | 
			
		||||
    targetCmp.$$.on_hmr = []
 | 
			
		||||
 | 
			
		||||
    // `conservative: true` means we want to be sure that the new component has
 | 
			
		||||
    // actually been successfuly created before destroying the old instance.
 | 
			
		||||
    // This could be useful for preventing runtime errors in component init to
 | 
			
		||||
    // bring down the whole HMR. Unfortunately the implementation bellow is
 | 
			
		||||
    // broken (FIXME), but that remains an interesting target for when HMR hooks
 | 
			
		||||
    // will actually land in Svelte itself.
 | 
			
		||||
    //
 | 
			
		||||
    // The goal would be to render an error inplace in case of error, to avoid
 | 
			
		||||
    // losing the navigation stack (especially annoying in native, that is not
 | 
			
		||||
    // based on URL navigation, so we lose the current page on each error).
 | 
			
		||||
    //
 | 
			
		||||
    targetCmp.$replace = (
 | 
			
		||||
      Component,
 | 
			
		||||
      {
 | 
			
		||||
        target = options.target,
 | 
			
		||||
        anchor = options.anchor,
 | 
			
		||||
        preserveLocalState,
 | 
			
		||||
        conservative = false,
 | 
			
		||||
      }
 | 
			
		||||
    ) => {
 | 
			
		||||
      const restore = captureState(targetCmp)
 | 
			
		||||
      assignOptions(
 | 
			
		||||
        target || options.target,
 | 
			
		||||
        anchor,
 | 
			
		||||
        restore,
 | 
			
		||||
        preserveLocalState
 | 
			
		||||
      )
 | 
			
		||||
 | 
			
		||||
      const callbacks = cmp ? cmp.$$.on_hmr : []
 | 
			
		||||
 | 
			
		||||
      const afterCallbacks = callbacks.map(fn => fn(cmp)).filter(Boolean)
 | 
			
		||||
 | 
			
		||||
      const previous = cmp
 | 
			
		||||
      if (conservative) {
 | 
			
		||||
        try {
 | 
			
		||||
          const next = createComponent(Component, restore, previous)
 | 
			
		||||
          // prevents on_destroy from firing on non-final cmp instance
 | 
			
		||||
          cmp = null
 | 
			
		||||
          previous.$destroy()
 | 
			
		||||
          cmp = next
 | 
			
		||||
        } catch (err) {
 | 
			
		||||
          cmp = previous
 | 
			
		||||
          throw err
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        // prevents on_destroy from firing on non-final cmp instance
 | 
			
		||||
        cmp = null
 | 
			
		||||
        if (previous) {
 | 
			
		||||
          // previous can be null if last constructor has crashed
 | 
			
		||||
          previous.$destroy()
 | 
			
		||||
        }
 | 
			
		||||
        cmp = createComponent(Component, restore, cmp)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      cmp.$$.hmr_cmp = cmp
 | 
			
		||||
 | 
			
		||||
      for (const fn of afterCallbacks) {
 | 
			
		||||
        fn(cmp)
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      cmp.$$.on_hmr = callbacks
 | 
			
		||||
 | 
			
		||||
      return cmp
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // NOTE onMount must provide target & anchor (for us to be able to determinate
 | 
			
		||||
    // 			actual DOM insertion point)
 | 
			
		||||
    //
 | 
			
		||||
    // 			And also, to support keyed list, it needs to be called each time the
 | 
			
		||||
    // 			component is moved (same as $$.fragment.m)
 | 
			
		||||
    if (onMount) {
 | 
			
		||||
      const m = targetCmp.$$.fragment.m
 | 
			
		||||
      targetCmp.$$.fragment.m = (...args) => {
 | 
			
		||||
        const result = m(...args)
 | 
			
		||||
        onMount(...args)
 | 
			
		||||
        return result
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // NOTE onDestroy must be called even if the call doesn't pass through the
 | 
			
		||||
    //      component's $destroy method (that we can hook onto by ourselves, since
 | 
			
		||||
    //      it's public API) -- this happens a lot in svelte's internals, that
 | 
			
		||||
    //      manipulates cmp.$$.fragment directly, often binding to fragment.d,
 | 
			
		||||
    //      for example
 | 
			
		||||
    if (onDestroy) {
 | 
			
		||||
      targetCmp.$$.on_destroy.push(() => {
 | 
			
		||||
        if (isCurrent(targetCmp)) {
 | 
			
		||||
          onDestroy()
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (onInstance) {
 | 
			
		||||
      onInstance(targetCmp)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Svelte 3 creates and mount components from their constructor if
 | 
			
		||||
    // options.target is present.
 | 
			
		||||
    //
 | 
			
		||||
    // This means that at this point, the component's `fragment.c` and,
 | 
			
		||||
    // most notably, `fragment.m` will already have been called _from inside
 | 
			
		||||
    // createComponent_. That is: before we have a chance to hook on it.
 | 
			
		||||
    //
 | 
			
		||||
    // Proxy's constructor
 | 
			
		||||
    //   -> createComponent
 | 
			
		||||
    //     -> component constructor
 | 
			
		||||
    //       -> component.$$.fragment.c(...) (or l, if hydrate:true)
 | 
			
		||||
    //       -> component.$$.fragment.m(...)
 | 
			
		||||
    //
 | 
			
		||||
    //   -> you are here <-
 | 
			
		||||
    //
 | 
			
		||||
    if (onMount) {
 | 
			
		||||
      const { target, anchor } = options
 | 
			
		||||
      if (target) {
 | 
			
		||||
        onMount(target, anchor)
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const parentComponent = allowLiveBinding
 | 
			
		||||
    ? current_component
 | 
			
		||||
    : get_current_component_safe()
 | 
			
		||||
 | 
			
		||||
  cmp = new Component(options)
 | 
			
		||||
  cmp.$$.hmr_cmp = cmp
 | 
			
		||||
 | 
			
		||||
  instrument(cmp)
 | 
			
		||||
 | 
			
		||||
  return cmp
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										62
									
								
								node_modules/svelte-hmr/runtime/svelte-native/patch-page-show-modal.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								node_modules/svelte-hmr/runtime/svelte-native/patch-page-show-modal.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
// This module monkey patches Page#showModal in order to be able to
 | 
			
		||||
// access from the HMR proxy data passed to `showModal` in svelte-native.
 | 
			
		||||
//
 | 
			
		||||
// Data are stored in a opaque prop accessible with `getModalData`.
 | 
			
		||||
//
 | 
			
		||||
// It also switches the `closeCallback` option with a custom brewed one
 | 
			
		||||
// in order to give the proxy control over when its own instance will be
 | 
			
		||||
// destroyed.
 | 
			
		||||
//
 | 
			
		||||
// Obviously this method suffer from extreme coupling with the target code
 | 
			
		||||
// in svelte-native. So it would be wise to recheck compatibility on SN
 | 
			
		||||
// version upgrades.
 | 
			
		||||
//
 | 
			
		||||
// Relevant code is there (last checked version):
 | 
			
		||||
//
 | 
			
		||||
// https://github.com/halfnelson/svelte-native/blob/48fdc97d2eb4d3958cfcb4ff6cf5755a220829eb/src/dom/navigation.ts#L132
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
// FIXME should we override ViewBase#showModal instead?
 | 
			
		||||
// eslint-disable-next-line import/no-unresolved
 | 
			
		||||
import { Page } from '@nativescript/core'
 | 
			
		||||
 | 
			
		||||
const prop =
 | 
			
		||||
  typeof Symbol !== 'undefined'
 | 
			
		||||
    ? Symbol('hmr_svelte_native_modal')
 | 
			
		||||
    : '___HMR_SVELTE_NATIVE_MODAL___'
 | 
			
		||||
 | 
			
		||||
const sup = Page.prototype.showModal
 | 
			
		||||
 | 
			
		||||
let patched = false
 | 
			
		||||
 | 
			
		||||
export const patchShowModal = () => {
 | 
			
		||||
  // guard: already patched
 | 
			
		||||
  if (patched) return
 | 
			
		||||
  patched = true
 | 
			
		||||
 | 
			
		||||
  Page.prototype.showModal = function(modalView, options) {
 | 
			
		||||
    const modalData = {
 | 
			
		||||
      originalOptions: options,
 | 
			
		||||
      closeCallback: options.closeCallback,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    modalView[prop] = modalData
 | 
			
		||||
 | 
			
		||||
    // Proxies to a function that can be swapped on the fly by HMR proxy.
 | 
			
		||||
    //
 | 
			
		||||
    // The default is still to call the original closeCallback from svelte
 | 
			
		||||
    // navtive, which will destroy the modal view & component. This way, if
 | 
			
		||||
    // no HMR happens on the modal content, normal behaviour is preserved
 | 
			
		||||
    // without the proxy having any work to do.
 | 
			
		||||
    //
 | 
			
		||||
    const closeCallback = (...args) => {
 | 
			
		||||
      return modalData.closeCallback(...args)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const tamperedOptions = Object.assign({}, options, { closeCallback })
 | 
			
		||||
 | 
			
		||||
    return sup.call(this, modalView, tamperedOptions)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const getModalData = modalView => modalView[prop]
 | 
			
		||||
							
								
								
									
										341
									
								
								node_modules/svelte-hmr/runtime/svelte-native/proxy-adapter-native.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										341
									
								
								node_modules/svelte-hmr/runtime/svelte-native/proxy-adapter-native.js
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,341 @@
 | 
			
		||||
/* global document */
 | 
			
		||||
 | 
			
		||||
import { adapter as ProxyAdapterDom } from '../proxy-adapter-dom'
 | 
			
		||||
 | 
			
		||||
import { patchShowModal, getModalData } from './patch-page-show-modal'
 | 
			
		||||
 | 
			
		||||
patchShowModal()
 | 
			
		||||
 | 
			
		||||
// Svelte Native support
 | 
			
		||||
// =====================
 | 
			
		||||
//
 | 
			
		||||
// Rerendering Svelte Native page proves challenging...
 | 
			
		||||
//
 | 
			
		||||
// In NativeScript, pages are the top level component. They are normally
 | 
			
		||||
// introduced into NativeScript's runtime by its `navigate` function. This
 | 
			
		||||
// is how Svelte Natives handles it: it renders the Page component to a
 | 
			
		||||
// dummy fragment, and "navigate" to the page element thus created.
 | 
			
		||||
//
 | 
			
		||||
// As long as modifications only impact child components of the page, then
 | 
			
		||||
// we can keep the existing page and replace its content for HMR.
 | 
			
		||||
//
 | 
			
		||||
// However, if the page component itself is modified (including its system
 | 
			
		||||
// title bar), things get hairy...
 | 
			
		||||
//
 | 
			
		||||
// Apparently, the sole way of introducing a new page in a NS application is
 | 
			
		||||
// to navigate to it (no way to just replace it in its parent "element", for
 | 
			
		||||
// example). This is how it is done in NS's own "core" HMR.
 | 
			
		||||
//
 | 
			
		||||
// NOTE The last paragraph has not really been confirmed with NS6.
 | 
			
		||||
//
 | 
			
		||||
// Unfortunately the API they're using to do that is not public... Its various
 | 
			
		||||
// parts remain exposed though (but documented as private), so this exploratory
 | 
			
		||||
// work now relies on it. It might be fragile...
 | 
			
		||||
//
 | 
			
		||||
// The problem is that there is no public API that can navigate to a page and
 | 
			
		||||
// replace (like location.replace) the current history entry. Actually there
 | 
			
		||||
// is an active issue at NS asking for that. Incidentally, members of
 | 
			
		||||
// NativeScript-Vue have commented on the issue to weight in for it -- they
 | 
			
		||||
// probably face some similar challenge.
 | 
			
		||||
//
 | 
			
		||||
// https://github.com/NativeScript/NativeScript/issues/6283
 | 
			
		||||
 | 
			
		||||
const getNavTransition = ({ transition }) => {
 | 
			
		||||
  if (typeof transition === 'string') {
 | 
			
		||||
    transition = { name: transition }
 | 
			
		||||
  }
 | 
			
		||||
  return transition ? { animated: true, transition } : { animated: false }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// copied from TNS FrameBase.replacePage
 | 
			
		||||
//
 | 
			
		||||
// it is not public but there is a comment in there indicating it is for
 | 
			
		||||
// HMR (probably their own core HMR though)
 | 
			
		||||
//
 | 
			
		||||
// NOTE this "worked" in TNS 5, but not anymore in TNS 6: updated version bellow
 | 
			
		||||
//
 | 
			
		||||
// eslint-disable-next-line no-unused-vars
 | 
			
		||||
const replacePage_tns5 = (frame, newPageElement, hotOptions) => {
 | 
			
		||||
  const currentBackstackEntry = frame._currentEntry
 | 
			
		||||
  frame.navigationType = 2
 | 
			
		||||
  frame.performNavigation({
 | 
			
		||||
    isBackNavigation: false,
 | 
			
		||||
    entry: {
 | 
			
		||||
      resolvedPage: newPageElement.nativeView,
 | 
			
		||||
      //
 | 
			
		||||
      // entry: currentBackstackEntry.entry,
 | 
			
		||||
      entry: Object.assign(
 | 
			
		||||
        currentBackstackEntry.entry,
 | 
			
		||||
        getNavTransition(hotOptions)
 | 
			
		||||
      ),
 | 
			
		||||
      navDepth: currentBackstackEntry.navDepth,
 | 
			
		||||
      fragmentTag: currentBackstackEntry.fragmentTag,
 | 
			
		||||
      frameId: currentBackstackEntry.frameId,
 | 
			
		||||
    },
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Updated for TNS v6
 | 
			
		||||
//
 | 
			
		||||
// https://github.com/NativeScript/NativeScript/blob/6.1.1/tns-core-modules/ui/frame/frame-common.ts#L656
 | 
			
		||||
const replacePage = (frame, newPageElement) => {
 | 
			
		||||
  const currentBackstackEntry = frame._currentEntry
 | 
			
		||||
  const newPage = newPageElement.nativeView
 | 
			
		||||
  const newBackstackEntry = {
 | 
			
		||||
    entry: currentBackstackEntry.entry,
 | 
			
		||||
    resolvedPage: newPage,
 | 
			
		||||
    navDepth: currentBackstackEntry.navDepth,
 | 
			
		||||
    fragmentTag: currentBackstackEntry.fragmentTag,
 | 
			
		||||
    frameId: currentBackstackEntry.frameId,
 | 
			
		||||
  }
 | 
			
		||||
  const navigationContext = {
 | 
			
		||||
    entry: newBackstackEntry,
 | 
			
		||||
    isBackNavigation: false,
 | 
			
		||||
    navigationType: 2 /* NavigationType replace */,
 | 
			
		||||
  }
 | 
			
		||||
  frame._navigationQueue.push(navigationContext)
 | 
			
		||||
  frame._processNextNavigationEntry()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const adapter = class ProxyAdapterNative extends ProxyAdapterDom {
 | 
			
		||||
  constructor(instance) {
 | 
			
		||||
    super(instance)
 | 
			
		||||
 | 
			
		||||
    this.nativePageElement = null
 | 
			
		||||
    this.originalNativeView = null
 | 
			
		||||
    this.navigatedFromHandler = null
 | 
			
		||||
 | 
			
		||||
    this.relayNativeNavigatedFrom = this.relayNativeNavigatedFrom.bind(this)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  dispose() {
 | 
			
		||||
    super.dispose()
 | 
			
		||||
    this.releaseNativePageElement()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  releaseNativePageElement() {
 | 
			
		||||
    if (this.nativePageElement) {
 | 
			
		||||
      // native cleaning will happen when navigating back from the page
 | 
			
		||||
      this.nativePageElement = null
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // svelte-native uses navigateFrom event + e.isBackNavigation to know
 | 
			
		||||
  // when to $destroy the component -- but we don't want our proxy instance
 | 
			
		||||
  // destroyed when we renavigate to the same page for navigation purposes!
 | 
			
		||||
  interceptPageNavigation(pageElement) {
 | 
			
		||||
    const originalNativeView = pageElement.nativeView
 | 
			
		||||
    const { on } = originalNativeView
 | 
			
		||||
    const ownOn = originalNativeView.hasOwnProperty('on')
 | 
			
		||||
    // tricks svelte-native into giving us its handler
 | 
			
		||||
    originalNativeView.on = function(type, handler) {
 | 
			
		||||
      if (type === 'navigatedFrom') {
 | 
			
		||||
        this.navigatedFromHandler = handler
 | 
			
		||||
        if (ownOn) {
 | 
			
		||||
          originalNativeView.on = on
 | 
			
		||||
        } else {
 | 
			
		||||
          delete originalNativeView.on
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        //some other handler wireup, we will just pass it on.
 | 
			
		||||
        if (on) {
 | 
			
		||||
          on(type, handler)
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  afterMount(target, anchor) {
 | 
			
		||||
    // nativePageElement needs to be updated each time (only for page
 | 
			
		||||
    // components, native component that are not pages follow normal flow)
 | 
			
		||||
    //
 | 
			
		||||
    // TODO quid of components that are initially a page, but then have the
 | 
			
		||||
    // <page> tag removed while running? or the opposite?
 | 
			
		||||
    //
 | 
			
		||||
    // insertionPoint needs to be updated _only when the target changes_ --
 | 
			
		||||
    // i.e. when the component is mount, i.e. (in svelte3) when the component
 | 
			
		||||
    // is _created_, and svelte3 doesn't allow it to move afterward -- that
 | 
			
		||||
    // is, insertionPoint only needs to be created once when the component is
 | 
			
		||||
    // first mounted.
 | 
			
		||||
    //
 | 
			
		||||
    // TODO is it really true that components' elements cannot move in the
 | 
			
		||||
    // DOM? what about keyed list?
 | 
			
		||||
    //
 | 
			
		||||
 | 
			
		||||
    const isNativePage =
 | 
			
		||||
      (target.tagName === 'fragment' || target.tagName === 'frame') &&
 | 
			
		||||
      target.firstChild &&
 | 
			
		||||
      target.firstChild.tagName == 'page'
 | 
			
		||||
    if (isNativePage) {
 | 
			
		||||
      const nativePageElement = target.firstChild
 | 
			
		||||
      this.interceptPageNavigation(nativePageElement)
 | 
			
		||||
      this.nativePageElement = nativePageElement
 | 
			
		||||
    } else {
 | 
			
		||||
      // try to protect against components changing from page to no-page
 | 
			
		||||
      // or vice versa -- see DEBUG 1 above. NOT TESTED so prolly not working
 | 
			
		||||
      this.nativePageElement = null
 | 
			
		||||
      super.afterMount(target, anchor)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  rerender() {
 | 
			
		||||
    const { nativePageElement } = this
 | 
			
		||||
    if (nativePageElement) {
 | 
			
		||||
      this.rerenderNative()
 | 
			
		||||
    } else {
 | 
			
		||||
      super.rerender()
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  rerenderNative() {
 | 
			
		||||
    const { nativePageElement: oldPageElement } = this
 | 
			
		||||
    const nativeView = oldPageElement.nativeView
 | 
			
		||||
    const frame = nativeView.frame
 | 
			
		||||
    if (frame) {
 | 
			
		||||
      return this.rerenderPage(frame, nativeView)
 | 
			
		||||
    }
 | 
			
		||||
    const modalParent = nativeView._modalParent // FIXME private API
 | 
			
		||||
    if (modalParent) {
 | 
			
		||||
      return this.rerenderModal(modalParent, nativeView)
 | 
			
		||||
    }
 | 
			
		||||
    // wtf? hopefully a race condition with a destroyed component, so
 | 
			
		||||
    // we have nothing more to do here
 | 
			
		||||
    //
 | 
			
		||||
    // for once, it happens when hot reloading dev deps, like this file
 | 
			
		||||
    //
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  rerenderPage(frame, previousPageView) {
 | 
			
		||||
    const isCurrentPage = frame.currentPage === previousPageView
 | 
			
		||||
    if (isCurrentPage) {
 | 
			
		||||
      const {
 | 
			
		||||
        instance: { hotOptions },
 | 
			
		||||
      } = this
 | 
			
		||||
      const newPageElement = this.createPage()
 | 
			
		||||
      if (!newPageElement) {
 | 
			
		||||
        throw new Error('Failed to create updated page')
 | 
			
		||||
      }
 | 
			
		||||
      const isFirstPage = !frame.canGoBack()
 | 
			
		||||
 | 
			
		||||
      if (isFirstPage) {
 | 
			
		||||
        // NOTE not so sure of bellow with the new NS6 method for replace
 | 
			
		||||
        //
 | 
			
		||||
        // The "replacePage" strategy does not work on the first page
 | 
			
		||||
        // of the stack.
 | 
			
		||||
        //
 | 
			
		||||
        // Resulting bug:
 | 
			
		||||
        // - launch
 | 
			
		||||
        // - change first page => HMR
 | 
			
		||||
        // - navigate to other page
 | 
			
		||||
        // - back
 | 
			
		||||
        //   => actual: back to OS
 | 
			
		||||
        //   => expected: back to page 1
 | 
			
		||||
        //
 | 
			
		||||
        // Fortunately, we can overwrite history in this case.
 | 
			
		||||
        //
 | 
			
		||||
        const nativeView = newPageElement.nativeView
 | 
			
		||||
        frame.navigate(
 | 
			
		||||
          Object.assign(
 | 
			
		||||
            {},
 | 
			
		||||
            {
 | 
			
		||||
              create: () => nativeView,
 | 
			
		||||
              clearHistory: true,
 | 
			
		||||
            },
 | 
			
		||||
            getNavTransition(hotOptions)
 | 
			
		||||
          )
 | 
			
		||||
        )
 | 
			
		||||
      } else {
 | 
			
		||||
        replacePage(frame, newPageElement, hotOptions)
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      const backEntry = frame.backStack.find(
 | 
			
		||||
        ({ resolvedPage: page }) => page === previousPageView
 | 
			
		||||
      )
 | 
			
		||||
      if (!backEntry) {
 | 
			
		||||
        // well... looks like we didn't make it to history after all
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
      // replace existing nativeView
 | 
			
		||||
      const newPageElement = this.createPage()
 | 
			
		||||
      if (newPageElement) {
 | 
			
		||||
        backEntry.resolvedPage = newPageElement.nativeView
 | 
			
		||||
      } else {
 | 
			
		||||
        throw new Error('Failed to create updated page')
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // modalParent is the page on which showModal(...) was called
 | 
			
		||||
  // oldPageElement is the modal content, that we're actually trying to reload
 | 
			
		||||
  rerenderModal(modalParent, modalView) {
 | 
			
		||||
    const modalData = getModalData(modalView)
 | 
			
		||||
 | 
			
		||||
    modalData.closeCallback = () => {
 | 
			
		||||
      const nativePageElement = this.createPage()
 | 
			
		||||
      if (!nativePageElement) {
 | 
			
		||||
        throw new Error('Failed to created updated modal page')
 | 
			
		||||
      }
 | 
			
		||||
      const { nativeView } = nativePageElement
 | 
			
		||||
      const { originalOptions } = modalData
 | 
			
		||||
      // Options will get monkey patched again, the only work left for us
 | 
			
		||||
      // is to try to reduce visual disturbances.
 | 
			
		||||
      //
 | 
			
		||||
      // FIXME Even that proves too much unfortunately... Apparently TNS
 | 
			
		||||
      // does not respect the `animated` option in this context:
 | 
			
		||||
      // https://docs.nativescript.org/api-reference/interfaces/_ui_core_view_base_.showmodaloptions#animated
 | 
			
		||||
      //
 | 
			
		||||
      const options = Object.assign({}, originalOptions, { animated: false })
 | 
			
		||||
      modalParent.showModal(nativeView, options)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    modalView.closeModal()
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  createPage() {
 | 
			
		||||
    const {
 | 
			
		||||
      instance: { refreshComponent },
 | 
			
		||||
    } = this
 | 
			
		||||
    const { nativePageElement, relayNativeNavigatedFrom } = this
 | 
			
		||||
    const oldNativeView = nativePageElement.nativeView
 | 
			
		||||
    // rerender
 | 
			
		||||
    const target = document.createElement('fragment')
 | 
			
		||||
    // not using conservative for now, since there's nothing in place here to
 | 
			
		||||
    // leverage it (yet?) -- and it might be easier to miss breakages in native
 | 
			
		||||
    // only code paths
 | 
			
		||||
    refreshComponent(target, null)
 | 
			
		||||
    // this.nativePageElement is updated in afterMount, triggered by proxy / hooks
 | 
			
		||||
    const newPageElement = this.nativePageElement
 | 
			
		||||
    // update event proxy
 | 
			
		||||
    oldNativeView.off('navigatedFrom', relayNativeNavigatedFrom)
 | 
			
		||||
    nativePageElement.nativeView.on('navigatedFrom', relayNativeNavigatedFrom)
 | 
			
		||||
    return newPageElement
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  relayNativeNavigatedFrom({ isBackNavigation }) {
 | 
			
		||||
    const { originalNativeView, navigatedFromHandler } = this
 | 
			
		||||
    if (!isBackNavigation) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
    if (originalNativeView) {
 | 
			
		||||
      const { off } = originalNativeView
 | 
			
		||||
      const ownOff = originalNativeView.hasOwnProperty('off')
 | 
			
		||||
      originalNativeView.off = function() {
 | 
			
		||||
        this.navigatedFromHandler = null
 | 
			
		||||
        if (ownOff) {
 | 
			
		||||
          originalNativeView.off = off
 | 
			
		||||
        } else {
 | 
			
		||||
          delete originalNativeView.off
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (navigatedFromHandler) {
 | 
			
		||||
      return navigatedFromHandler.apply(this, arguments)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  renderError(err /* , target, anchor */) {
 | 
			
		||||
    // TODO fallback on TNS error handler for now... at least our error
 | 
			
		||||
    // is more informative
 | 
			
		||||
    throw err
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user