-
Notifications
You must be signed in to change notification settings - Fork 439
Expand file tree
/
Copy pathcontext.ts
More file actions
91 lines (80 loc) · 2.84 KB
/
context.ts
File metadata and controls
91 lines (80 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/*
* Copyright (c) 2024, salesforce.com, inc.
* All rights reserved.
* SPDX-License-Identifier: MIT
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
*/
import {
type ContextProvidedCallback,
type ContextBinding as IContextBinding,
isTrustedContext,
getContextKeys,
isUndefined,
keys,
ArrayFilter,
} from '@lwc/shared';
import { getContextfulStack } from './wire';
import { type LightningElement, SYMBOL__CONTEXT_VARIETIES } from './lightning-element';
import type { Signal } from '@lwc/signals';
class ContextBinding<C extends LightningElement> implements IContextBinding<LightningElement> {
component: C;
constructor(component: C) {
this.component = component;
}
provideContext<V extends object>(
contextVariety: V,
providedContextSignal: Signal<unknown>
): void {
const contextVarieties = this.component[SYMBOL__CONTEXT_VARIETIES];
if (contextVarieties.has(contextVariety)) {
if (process.env.NODE_ENV !== 'production') {
throw new Error('Multiple contexts of the same variety were provided.');
}
return;
}
contextVarieties.set(contextVariety, providedContextSignal);
}
consumeContext<V extends object>(
contextVariety: V,
contextProvidedCallback: ContextProvidedCallback
): void {
const contextfulStack = getContextfulStack(this.component);
for (const ancestor of contextfulStack) {
// If the ancestor has the specified context variety, consume it and stop searching
const ancestorContextVarieties = ancestor[SYMBOL__CONTEXT_VARIETIES];
if (ancestorContextVarieties.has(contextVariety)) {
contextProvidedCallback(ancestorContextVarieties.get(contextVariety));
break;
}
}
}
}
export { ContextBinding };
export function connectContext(le: LightningElement) {
const contextKeys = getContextKeys();
if (isUndefined(contextKeys)) {
return;
}
const { connectContext } = contextKeys;
const enumerableKeys = keys(le);
const contextfulKeys = ArrayFilter.call(enumerableKeys, (enumerableKey) =>
isTrustedContext((le as any)[enumerableKey])
);
if (contextfulKeys.length === 0) {
return;
}
try {
for (let i = 0; i < contextfulKeys.length; i++) {
(le as any)[contextfulKeys[i]][connectContext](new ContextBinding(le));
}
} catch (err: any) {
if (process.env.NODE_ENV !== 'production') {
// eslint-disable-next-line preserve-caught-error
throw new Error(
`Attempted to connect to trusted context but received the following error: ${
err.message
}`
);
}
}
}