Skip to content

Commit 5f10eef

Browse files
committed
chore: address feedback
1 parent 586318e commit 5f10eef

File tree

5 files changed

+90
-6
lines changed

5 files changed

+90
-6
lines changed

packages/@lwc/engine-core/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ This experimental API enables the sanitization of HTML content by external servi
116116

117117
This experimental API enables the removal of an object's observable membrane proxy wrapper.
118118

119-
### setSignalValidator()
119+
### setTrustedSignalSet()
120120

121-
This experimental API enables the addition of a signal as a trusted signal. If the [`ENABLE_EXPERIMENTAL_SIGNALS`](https://github.com/salesforce/lwc/blob/master/packages/%40lwc/features/README.md#lwcfeatures) feature is enabled, any signal value change will trigger a re-render.
121+
This experimental API enables the addition of a signal as a trusted signal. If the [ENABLE_EXPERIMENTAL_SIGNALS](https://github.com/salesforce/lwc/blob/master/packages/%40lwc/features/README.md#lwcfeatures) feature is enabled, any signal value change will trigger a re-render.
122+
123+
If `setTrustedSignalSet` is called more than once, it will throw an error. If it is never called, then no trusted signal validation will be performed. The same `setTrustedSignalSet` API must be called on both `@lwc/engine-dom` and `@lwc/signals`.

packages/@lwc/engine-core/src/framework/mutation-tracker.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* SPDX-License-Identifier: MIT
55
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
66
*/
7-
import { isNull, isObject, isTrustedSignal } from '@lwc/shared';
7+
import { isFunction, isNull, isObject, isTrustedSignal } from '@lwc/shared';
88
import { Signal } from '@lwc/signals';
99
import {
1010
JobFunction,
@@ -46,6 +46,9 @@ export function componentValueObserved(vm: VM, key: PropertyKey, target: any = {
4646
lwcRuntimeFlags.ENABLE_EXPERIMENTAL_SIGNALS &&
4747
isObject(target) &&
4848
!isNull(target) &&
49+
'value' in target &&
50+
'subscribe' in target &&
51+
isFunction(target.subscribe) &&
4952
isTrustedSignal(target) &&
5053
// Only subscribe if a template is being rendered by the engine
5154
tro.isObserving()

packages/@lwc/integration-karma/test/signal/protocol/index.spec.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,18 @@ describe('signal protocol', () => {
183183
expect(elm.getSignalRemovedSubscriberCount()).toBe(2);
184184
});
185185

186+
it('does not subscribe if the signal shape is incorrect', async () => {
187+
const elm = createElement('x-child', { is: Child });
188+
const subscribe = jasmine.createSpy();
189+
// Note the signals property is value's' and not value
190+
const signal = { values: 'initial value', subscribe };
191+
elm.signal = signal;
192+
document.body.appendChild(elm);
193+
await Promise.resolve();
194+
195+
expect(subscribe).not.toHaveBeenCalled();
196+
});
197+
186198
it('does not subscribe if the signal is not added as trusted signal', async () => {
187199
const elm = createElement('x-child', { is: Child });
188200
const subscribe = jasmine.createSpy();
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* SPDX-License-Identifier: MIT
5+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6+
*/
7+
import { vi } from 'vitest';
8+
9+
describe('signals', () => {
10+
let setTrustedSignalSet: (signals: WeakSet<object>) => void;
11+
let addTrustedSignal: (signal: object) => void;
12+
let isTrustedSignal: (target: object) => boolean;
13+
14+
beforeEach(async () => {
15+
vi.resetModules();
16+
const signalsModule = await import('../signals');
17+
setTrustedSignalSet = signalsModule.setTrustedSignalSet;
18+
addTrustedSignal = signalsModule.addTrustedSignal;
19+
isTrustedSignal = signalsModule.isTrustedSignal;
20+
});
21+
22+
describe('setTrustedSignalSet', () => {
23+
it('should throw an error if trustedSignals is already set', () => {
24+
setTrustedSignalSet(new WeakSet());
25+
expect(() => setTrustedSignalSet(new WeakSet())).toThrow(
26+
'Trusted Signal Set is already set!'
27+
);
28+
});
29+
});
30+
31+
describe('addTrustedSignal', () => {
32+
it('should add a signal to the trustedSignals set', () => {
33+
const mockWeakSet = new WeakSet();
34+
setTrustedSignalSet(mockWeakSet);
35+
const signal = {};
36+
addTrustedSignal(signal);
37+
expect(isTrustedSignal(signal)).toBe(true);
38+
});
39+
});
40+
41+
describe('isTrustedSignal', () => {
42+
it('should return true for a trusted signal', () => {
43+
const mockWeakSet = new WeakSet();
44+
setTrustedSignalSet(mockWeakSet);
45+
const signal = {};
46+
addTrustedSignal(signal);
47+
expect(isTrustedSignal(signal)).toBe(true);
48+
});
49+
50+
it('should return false for an untrusted signal', () => {
51+
const mockWeakSet = new WeakSet();
52+
setTrustedSignalSet(mockWeakSet);
53+
expect(isTrustedSignal({})).toBe(false);
54+
});
55+
56+
it('should return true for all calls when trustedSignals is not set', () => {
57+
expect(isTrustedSignal({})).toBe(true);
58+
});
59+
});
60+
});

packages/@lwc/shared/src/signals.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,23 @@ import { isFalse } from './assert';
88

99
let trustedSignals: WeakSet<object>;
1010

11-
export function setSignalValidator(signals: WeakSet<object>) {
12-
isFalse(trustedSignals, 'Already added a signal validator');
11+
export function setTrustedSignalSet(signals: WeakSet<object>) {
12+
isFalse(trustedSignals, 'Trusted Signal Set is already set!');
1313

1414
trustedSignals = signals;
1515
}
1616

1717
export function addTrustedSignal(signal: object) {
18+
// This should be a no-op when the trustedSignals set isn't set by runtime
1819
trustedSignals?.add(signal);
1920
}
2021

2122
export function isTrustedSignal(target: object): boolean {
22-
return trustedSignals?.has(target);
23+
if (!trustedSignals) {
24+
// The runtime didn't set a trustedSignals set
25+
// this check should only be performed for runtimes that care about filtering signals to track
26+
// our default behavior should be to track all signals
27+
return true;
28+
}
29+
return trustedSignals.has(target);
2330
}

0 commit comments

Comments
 (0)