Home / File/ create-subscriber.js — svelte Source File

create-subscriber.js — svelte Source File

Architecture documentation for create-subscriber.js, a javascript file in the svelte codebase. 15 imports, 3 dependents.

File javascript SharedInternal DOMUtils 15 imports 3 dependents 1 functions

Entity Profile

Dependency Diagram

graph LR
  9ad5fe9f_fc6f_e854_93df_194b16c3b738["create-subscriber.js"]
  bde4209f_8ffc_1594_4024_b1835a44bcf6["runtime.js"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> bde4209f_8ffc_1594_4024_b1835a44bcf6
  a08b6cc5_af73_1be4_d02f_3113cf8a8305["get"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> a08b6cc5_af73_1be4_d02f_3113cf8a8305
  a53cae39_471c_2887_0e0b_eedb385d245a["tick"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> a53cae39_471c_2887_0e0b_eedb385d245a
  a814b193_e12a_4037_c3c8_dfd45f3bd0bb["untrack"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> a814b193_e12a_4037_c3c8_dfd45f3bd0bb
  1ae6fa4e_16ee_acdf_5e28_17eb0819fddb["effects.js"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 1ae6fa4e_16ee_acdf_5e28_17eb0819fddb
  461d1f5f_ffa4_d984_98a4_868566c66f30["effect_tracking"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 461d1f5f_ffa4_d984_98a4_868566c66f30
  7494b934_a3b8_689e_91b6_8435e26461c5["render_effect"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 7494b934_a3b8_689e_91b6_8435e26461c5
  e5c35d51_28d8_9054_923d_b7f82a3c8dc2["sources.js"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> e5c35d51_28d8_9054_923d_b7f82a3c8dc2
  1e2f7428_6050_5cb7_69db_bf5db719f6d1["source"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 1e2f7428_6050_5cb7_69db_bf5db719f6d1
  7602fc38_fab9_8955_83f0_8643d7c6c7a4["increment"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 7602fc38_fab9_8955_83f0_8643d7c6c7a4
  2696eb67_452f_4c32_3e13_ee172192b366["tracing.js"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 2696eb67_452f_4c32_3e13_ee172192b366
  4dfcf957_8573_ff55_bd31_4181227109e3["tag"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 4dfcf957_8573_ff55_bd31_4181227109e3
  8e9a8b22_9754_09a3_8bf1_af0aeb68deca["task.js"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 8e9a8b22_9754_09a3_8bf1_af0aeb68deca
  2cab0f64_6d19_d981_66e2_d2555c252702["queue_micro_task"]
  9ad5fe9f_fc6f_e854_93df_194b16c3b738 --> 2cab0f64_6d19_d981_66e2_d2555c252702
  style 9ad5fe9f_fc6f_e854_93df_194b16c3b738 fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

import { get, tick, untrack } from '../internal/client/runtime.js';
import { effect_tracking, render_effect } from '../internal/client/reactivity/effects.js';
import { source, increment } from '../internal/client/reactivity/sources.js';
import { tag } from '../internal/client/dev/tracing.js';
import { DEV } from 'esm-env';
import { queue_micro_task } from '../internal/client/dom/task.js';

/**
 * Returns a `subscribe` function that integrates external event-based systems with Svelte's reactivity.
 * It's particularly useful for integrating with web APIs like `MediaQuery`, `IntersectionObserver`, or `WebSocket`.
 *
 * If `subscribe` is called inside an effect (including indirectly, for example inside a getter),
 * the `start` callback will be called with an `update` function. Whenever `update` is called, the effect re-runs.
 *
 * If `start` returns a cleanup function, it will be called when the effect is destroyed.
 *
 * If `subscribe` is called in multiple effects, `start` will only be called once as long as the effects
 * are active, and the returned teardown function will only be called when all effects are destroyed.
 *
 * It's best understood with an example. Here's an implementation of [`MediaQuery`](https://svelte.dev/docs/svelte/svelte-reactivity#MediaQuery):
 *
 * ```js
 * import { createSubscriber } from 'svelte/reactivity';
 * import { on } from 'svelte/events';
 *
 * export class MediaQuery {
 * 	#query;
 * 	#subscribe;
 *
 * 	constructor(query) {
 * 		this.#query = window.matchMedia(`(${query})`);
 *
 * 		this.#subscribe = createSubscriber((update) => {
 * 			// when the `change` event occurs, re-run any effects that read `this.current`
 * 			const off = on(this.#query, 'change', update);
 *
 * 			// stop listening when all the effects are destroyed
 * 			return () => off();
 * 		});
 * 	}
 *
 * 	get current() {
 * 		// This makes the getter reactive, if read in an effect
 * 		this.#subscribe();
 *
 * 		// Return the current state of the query, whether or not we're in an effect
 * 		return this.#query.matches;
 * 	}
 * }
 * ```
 * @param {(update: () => void) => (() => void) | void} start
 * @since 5.7.0
 */
export function createSubscriber(start) {
	let subscribers = 0;
	let version = source(0);
	/** @type {(() => void) | void} */
	let stop;

	if (DEV) {
		tag(version, 'createSubscriber version');
	}

	return () => {
		if (effect_tracking()) {
			get(version);

			render_effect(() => {
				if (subscribers === 0) {
					stop = untrack(() => start(() => increment(version)));
				}

				subscribers += 1;

				return () => {
					queue_micro_task(() => {
						// Only count down after a microtask, else we would reach 0 before our own render effect reruns,
						// but reach 1 again when the tick callback of the prior teardown runs. That would mean we
						// re-subcribe unnecessarily and create a memory leak because the old subscription is never cleaned up.
						subscribers -= 1;

						if (subscribers === 0) {
							stop?.();
							stop = undefined;
							// Increment the version to ensure any dependent deriveds are marked dirty when the subscription is picked up again later.
							// If we didn't do this then the comparison of write versions would determine that the derived has a later version than
							// the subscriber, and it would not be re-run.
							increment(version);
						}
					});
				};
			});
		}
	};
}

Subdomains

Functions

Frequently Asked Questions

What does create-subscriber.js do?
create-subscriber.js is a source file in the svelte codebase, written in javascript. It belongs to the SharedInternal domain, DOMUtils subdomain.
What functions are defined in create-subscriber.js?
create-subscriber.js defines 1 function(s): createSubscriber.
What does create-subscriber.js depend on?
create-subscriber.js imports 15 module(s): effect_tracking, effects.js, esm-env, get, increment, queue_micro_task, render_effect, runtime.js, and 7 more.
What files import create-subscriber.js?
create-subscriber.js is imported by 3 file(s): boundary.js, index-client.js, reactive-value.js.
Where is create-subscriber.js in the architecture?
create-subscriber.js is located at packages/svelte/src/reactivity/create-subscriber.js (domain: SharedInternal, subdomain: DOMUtils, directory: packages/svelte/src/reactivity).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free