mirror of https://github.com/sveltejs/svelte
chore: deduplicate client/server context helpers (#18580)
The server copy of `createContext` shipped without the `missing_context` throw and #17580 had to hand-mirror the client body back in, so this duplication has already cost a bug. This moves the realm-independent parts, the `createContext` tuple, `get_parent_context`, and `get_or_init_context_map`, into `internal/shared/context.js`, and each realm keeps its public context functions as thin wrappers over its own state.pull/18537/merge
parent
388840b1b2
commit
3feb34a992
@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
'svelte': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
chore: deduplicate client and server context helpers
|
||||||
@ -0,0 +1,52 @@
|
|||||||
|
import { lifecycle_outside_component, missing_context } from './errors.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template T
|
||||||
|
* @param {(key: object) => T} get_context
|
||||||
|
* @param {(key: object, context: T) => T} set_context
|
||||||
|
* @param {(key: object) => boolean} has_context
|
||||||
|
* @returns {[() => T, (context: T) => T]}
|
||||||
|
*/
|
||||||
|
export function create_context(get_context, set_context, has_context) {
|
||||||
|
const key = {};
|
||||||
|
|
||||||
|
return [
|
||||||
|
() => {
|
||||||
|
if (!has_context(key)) {
|
||||||
|
missing_context();
|
||||||
|
}
|
||||||
|
|
||||||
|
return get_context(key);
|
||||||
|
},
|
||||||
|
(context) => set_context(key, context)
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{ p: Context | null, c: Map<unknown, unknown> | null }} Context
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Context} context
|
||||||
|
* @returns {Map<unknown, unknown> | null}
|
||||||
|
*/
|
||||||
|
function get_parent_context(context) {
|
||||||
|
let parent = context.p;
|
||||||
|
while (parent !== null && parent.c === null) {
|
||||||
|
parent = parent.p;
|
||||||
|
}
|
||||||
|
return parent?.c ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Context | null} context
|
||||||
|
* @param {string} name
|
||||||
|
* @returns {Map<unknown, unknown>}
|
||||||
|
*/
|
||||||
|
export function get_or_init_context_map(context, name) {
|
||||||
|
if (context === null) {
|
||||||
|
lifecycle_outside_component(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (context.c ??= new Map(get_parent_context(context) || undefined));
|
||||||
|
}
|
||||||
Loading…
Reference in new issue