/ node_modules / svelte / src / runtime / internal / lifecycle.js
lifecycle.js
  1  import { custom_event } from './dom.js';
  2  
  3  export let current_component;
  4  
  5  /** @returns {void} */
  6  export function set_current_component(component) {
  7  	current_component = component;
  8  }
  9  
 10  export function get_current_component() {
 11  	if (!current_component) throw new Error('Function called outside component initialization');
 12  	return current_component;
 13  }
 14  
 15  /**
 16   * Schedules a callback to run immediately before the component is updated after any state change.
 17   *
 18   * The first time the callback runs will be before the initial `onMount`
 19   *
 20   * https://svelte.dev/docs/svelte#beforeupdate
 21   * @param {() => any} fn
 22   * @returns {void}
 23   */
 24  export function beforeUpdate(fn) {
 25  	get_current_component().$$.before_update.push(fn);
 26  }
 27  
 28  /**
 29   * The `onMount` function schedules a callback to run as soon as the component has been mounted to the DOM.
 30   * It must be called during the component's initialisation (but doesn't need to live *inside* the component;
 31   * it can be called from an external module).
 32   *
 33   * If a function is returned _synchronously_ from `onMount`, it will be called when the component is unmounted.
 34   *
 35   * `onMount` does not run inside a [server-side component](https://svelte.dev/docs#run-time-server-side-component-api).
 36   *
 37   * https://svelte.dev/docs/svelte#onmount
 38   * @template T
 39   * @param {() => import('./private.js').NotFunction<T> | Promise<import('./private.js').NotFunction<T>> | (() => any)} fn
 40   * @returns {void}
 41   */
 42  export function onMount(fn) {
 43  	get_current_component().$$.on_mount.push(fn);
 44  }
 45  
 46  /**
 47   * Schedules a callback to run immediately after the component has been updated.
 48   *
 49   * The first time the callback runs will be after the initial `onMount`
 50   *
 51   * https://svelte.dev/docs/svelte#afterupdate
 52   * @param {() => any} fn
 53   * @returns {void}
 54   */
 55  export function afterUpdate(fn) {
 56  	get_current_component().$$.after_update.push(fn);
 57  }
 58  
 59  /**
 60   * Schedules a callback to run immediately before the component is unmounted.
 61   *
 62   * Out of `onMount`, `beforeUpdate`, `afterUpdate` and `onDestroy`, this is the
 63   * only one that runs inside a server-side component.
 64   *
 65   * https://svelte.dev/docs/svelte#ondestroy
 66   * @param {() => any} fn
 67   * @returns {void}
 68   */
 69  export function onDestroy(fn) {
 70  	get_current_component().$$.on_destroy.push(fn);
 71  }
 72  
 73  /**
 74   * Creates an event dispatcher that can be used to dispatch [component events](https://svelte.dev/docs#template-syntax-component-directives-on-eventname).
 75   * Event dispatchers are functions that can take two arguments: `name` and `detail`.
 76   *
 77   * Component events created with `createEventDispatcher` create a
 78   * [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent).
 79   * These events do not [bubble](https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Building_blocks/Events#Event_bubbling_and_capture).
 80   * The `detail` argument corresponds to the [CustomEvent.detail](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail)
 81   * property and can contain any type of data.
 82   *
 83   * The event dispatcher can be typed to narrow the allowed event names and the type of the `detail` argument:
 84   * ```ts
 85   * const dispatch = createEventDispatcher<{
 86   *  loaded: never; // does not take a detail argument
 87   *  change: string; // takes a detail argument of type string, which is required
 88   *  optional: number | null; // takes an optional detail argument of type number
 89   * }>();
 90   * ```
 91   *
 92   * https://svelte.dev/docs/svelte#createeventdispatcher
 93   * @template {Record<string, any>} [EventMap=any]
 94   * @returns {import('./public.js').EventDispatcher<EventMap>}
 95   */
 96  export function createEventDispatcher() {
 97  	const component = get_current_component();
 98  	return (type, detail, { cancelable = false } = {}) => {
 99  		const callbacks = component.$$.callbacks[type];
100  		if (callbacks) {
101  			// TODO are there situations where events could be dispatched
102  			// in a server (non-DOM) environment?
103  			const event = custom_event(/** @type {string} */ (type), detail, { cancelable });
104  			callbacks.slice().forEach((fn) => {
105  				fn.call(component, event);
106  			});
107  			return !event.defaultPrevented;
108  		}
109  		return true;
110  	};
111  }
112  
113  /**
114   * Associates an arbitrary `context` object with the current component and the specified `key`
115   * and returns that object. The context is then available to children of the component
116   * (including slotted content) with `getContext`.
117   *
118   * Like lifecycle functions, this must be called during component initialisation.
119   *
120   * https://svelte.dev/docs/svelte#setcontext
121   * @template T
122   * @param {any} key
123   * @param {T} context
124   * @returns {T}
125   */
126  export function setContext(key, context) {
127  	get_current_component().$$.context.set(key, context);
128  	return context;
129  }
130  
131  /**
132   * Retrieves the context that belongs to the closest parent component with the specified `key`.
133   * Must be called during component initialisation.
134   *
135   * https://svelte.dev/docs/svelte#getcontext
136   * @template T
137   * @param {any} key
138   * @returns {T}
139   */
140  export function getContext(key) {
141  	return get_current_component().$$.context.get(key);
142  }
143  
144  /**
145   * Retrieves the whole context map that belongs to the closest parent component.
146   * Must be called during component initialisation. Useful, for example, if you
147   * programmatically create a component and want to pass the existing context to it.
148   *
149   * https://svelte.dev/docs/svelte#getallcontexts
150   * @template {Map<any, any>} [T=Map<any, any>]
151   * @returns {T}
152   */
153  export function getAllContexts() {
154  	return get_current_component().$$.context;
155  }
156  
157  /**
158   * Checks whether a given `key` has been set in the context of a parent component.
159   * Must be called during component initialisation.
160   *
161   * https://svelte.dev/docs/svelte#hascontext
162   * @param {any} key
163   * @returns {boolean}
164   */
165  export function hasContext(key) {
166  	return get_current_component().$$.context.has(key);
167  }
168  
169  // TODO figure out if we still want to support
170  // shorthand events, or if we want to implement
171  // a real bubbling mechanism
172  /**
173   * @param component
174   * @param event
175   * @returns {void}
176   */
177  export function bubble(component, event) {
178  	const callbacks = component.$$.callbacks[event.type];
179  	if (callbacks) {
180  		// @ts-ignore
181  		callbacks.slice().forEach((fn) => fn.call(this, event));
182  	}
183  }