Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@wordpress/interactivity

Package Overview
Dependencies
Maintainers
0
Versions
74
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@wordpress/interactivity - npm Package Compare versions

Comparing version 6.9.0 to 6.10.0

48

build-module/directives.js

@@ -0,1 +1,2 @@

/* wp:polyfill */
// eslint-disable-next-line eslint-comments/disable-enable-pair

@@ -14,3 +15,3 @@ /* eslint-disable react-hooks/exhaustive-deps */

import { useWatch, useInit, kebabToCamelCase, warn, splitTask, isPlainObject } from './utils';
import { directive, getEvaluate } from './hooks';
import { directive, getEvaluate, isDefaultDirectiveSuffix, isNonDefaultDirectiveSuffix } from './hooks';
import { getScope } from './scopes';

@@ -75,5 +76,3 @@ import { proxifyState, proxifyContext, deepMerge } from './proxies';

}) => {
directives[`on-${type}`].filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
directives[`on-${type}`].filter(isNonDefaultDirectiveSuffix).forEach(entry => {
const eventName = entry.suffix.split('--', 1)[0];

@@ -101,5 +100,3 @@ useInit(() => {

}) => {
directives[`on-async-${type}`].filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
directives[`on-async-${type}`].filter(isNonDefaultDirectiveSuffix).forEach(entry => {
const eventName = entry.suffix.split('--', 1)[0];

@@ -120,3 +117,3 @@ useInit(() => {

};
export default (() => {
export default () => {
// data-wp-context

@@ -135,5 +132,3 @@ directive('context', ({

} = inheritedContext;
const defaultEntry = context.find(({
suffix
}) => suffix === 'default');
const defaultEntry = context.find(isDefaultDirectiveSuffix);
const {

@@ -262,5 +257,3 @@ client: inheritedClient,

const events = new Map();
on.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
on.filter(isNonDefaultDirectiveSuffix).forEach(entry => {
const event = entry.suffix.split('--')[0];

@@ -314,5 +307,3 @@ if (!events.has(event)) {

const events = new Map();
onAsync.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
onAsync.filter(isNonDefaultDirectiveSuffix).forEach(entry => {
const event = entry.suffix.split('--')[0];

@@ -356,5 +347,3 @@ if (!events.has(event)) {

}) => {
classNames.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
classNames.filter(isNonDefaultDirectiveSuffix).forEach(entry => {
const className = entry.suffix;

@@ -392,5 +381,3 @@ const result = evaluate(entry);

}) => {
style.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
style.filter(isNonDefaultDirectiveSuffix).forEach(entry => {
const styleProp = entry.suffix;

@@ -430,5 +417,3 @@ const result = evaluate(entry);

}) => {
bind.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
bind.filter(isNonDefaultDirectiveSuffix).forEach(entry => {
const attribute = entry.suffix;

@@ -517,5 +502,3 @@ const result = evaluate(entry);

}) => {
const entry = text.find(({
suffix
}) => suffix === 'default');
const entry = text.find(isDefaultDirectiveSuffix);
if (!entry) {

@@ -562,8 +545,7 @@ element.props.children = null;

const {
namespace,
suffix
namespace
} = entry;
const list = evaluate(entry);
const itemProp = isNonDefaultDirectiveSuffix(entry) ? kebabToCamelCase(entry.suffix) : 'item';
return list.map(item => {
const itemProp = suffix === 'default' ? 'item' : kebabToCamelCase(suffix);
const itemContext = proxifyContext(proxifyState(namespace, {}), inheritedValue.client[namespace]);

@@ -601,3 +583,3 @@ const mergedContext = {

});
});
};
//# sourceMappingURL=directives.js.map

@@ -15,2 +15,8 @@ // eslint-disable-next-line eslint-comments/disable-enable-pair

import { getScope, setScope, resetScope } from './scopes';
export function isNonDefaultDirectiveSuffix(entry) {
return entry.suffix !== null;
}
export function isDefaultDirectiveSuffix(entry) {
return entry.suffix === null;
}
// Main context.

@@ -34,3 +40,3 @@ const context = createContext({

* ( { directives: { alert }, element, evaluate } ) => {
* const defaultEntry = alert.find( entry => entry.suffix === 'default' );
* const defaultEntry = alert.find( isDefaultDirectiveSuffix );
* element.props.onclick = () => { alert( evaluate( defaultEntry ) ); }

@@ -54,3 +60,3 @@ * }

* Note that, in the previous example, the directive callback gets the path
* value (`state.alert`) from the directive entry with suffix `default`. A
* value (`state.alert`) from the directive entry with suffix `null`. A
* custom suffix can also be specified by appending `--` to the directive

@@ -231,5 +237,3 @@ * attribute, followed by the suffix, like in the following HTML snippet:

if (directives.key) {
vnode.key = directives.key.find(({
suffix
}) => suffix === 'default').value;
vnode.key = directives.key.find(isDefaultDirectiveSuffix).value;
}

@@ -236,0 +240,0 @@ delete props.__directives;

@@ -0,1 +1,2 @@

/* wp:polyfill */
const contextObjectToProxy = new WeakMap();

@@ -2,0 +3,0 @@ const contextObjectToFallback = new WeakMap();

@@ -0,1 +1,2 @@

/* wp:polyfill */
/**

@@ -2,0 +3,0 @@ * Proxies for each object.

@@ -0,1 +1,2 @@

/* wp:polyfill */
/**

@@ -246,39 +247,43 @@ * External dependencies

const deepMergeRecursive = (target, source, override = true) => {
if (isPlainObject(target) && isPlainObject(source)) {
let hasNewKeys = false;
for (const key in source) {
const isNew = !(key in target);
hasNewKeys = hasNewKeys || isNew;
const desc = Object.getOwnPropertyDescriptor(source, key);
if (typeof desc?.get === 'function' || typeof desc?.set === 'function') {
if (override || isNew) {
Object.defineProperty(target, key, {
...desc,
configurable: true,
enumerable: true
});
const proxy = getProxyFromObject(target);
if (desc?.get && proxy && hasPropSignal(proxy, key)) {
const propSignal = getPropSignal(proxy, key);
propSignal.setGetter(desc.get);
}
if (!(isPlainObject(target) && isPlainObject(source))) {
return;
}
let hasNewKeys = false;
for (const key in source) {
const isNew = !(key in target);
hasNewKeys = hasNewKeys || isNew;
const desc = Object.getOwnPropertyDescriptor(source, key);
const proxy = getProxyFromObject(target);
const propSignal = !!proxy && hasPropSignal(proxy, key) && getPropSignal(proxy, key);
if (typeof desc.get === 'function' || typeof desc.set === 'function') {
if (override || isNew) {
Object.defineProperty(target, key, {
...desc,
configurable: true,
enumerable: true
});
if (desc.get && propSignal) {
propSignal.setGetter(desc.get);
}
} else if (isPlainObject(source[key])) {
if (isNew) {
target[key] = {};
}
} else if (isPlainObject(source[key])) {
if (isNew || override && !isPlainObject(target[key])) {
target[key] = {};
if (propSignal) {
propSignal.setValue(target[key]);
}
}
if (isPlainObject(target[key])) {
deepMergeRecursive(target[key], source[key], override);
} else if (override || isNew) {
Object.defineProperty(target, key, desc);
const proxy = getProxyFromObject(target);
if (desc?.value && proxy && hasPropSignal(proxy, key)) {
const propSignal = getPropSignal(proxy, key);
propSignal.setValue(desc.value);
}
}
} else if (override || isNew) {
Object.defineProperty(target, key, desc);
if (propSignal) {
propSignal.setValue(desc.value);
}
}
if (hasNewKeys && objToIterable.has(target)) {
objToIterable.get(target).value++;
}
}
if (hasNewKeys && objToIterable.has(target)) {
objToIterable.get(target).value++;
}
};

@@ -285,0 +290,0 @@

@@ -0,1 +1,2 @@

/* wp:polyfill */
/**

@@ -38,5 +39,4 @@ * External dependencies

*/
export const splitTask = () => {
export const splitTask = typeof window.scheduler?.yield === 'function' ? window.scheduler.yield.bind(window.scheduler) : () => {
return new Promise(resolve => {
// TODO: Use scheduler.yield() when available.
setTimeout(resolve, 0);

@@ -43,0 +43,0 @@ });

@@ -133,7 +133,7 @@ /**

const prefix = directiveMatch[1] || '';
const suffix = directiveMatch[2] || 'default';
const suffix = directiveMatch[2] || null;
obj[prefix] = obj[prefix] || [];
obj[prefix].push({
namespace: ns !== null && ns !== void 0 ? ns : currentNamespace(),
value,
value: value,
suffix

@@ -144,4 +144,2 @@ });

}
// @ts-expect-error Fixed in upcoming preact release https://github.com/preactjs/preact/pull/4334
if (localName === 'template') {

@@ -148,0 +146,0 @@ props.content = [...elementNode.content.childNodes].map(childNode => toVdom(childNode));

@@ -10,4 +10,12 @@ /**

namespace: string;
suffix: string | null;
}
export interface NonDefaultSuffixDirectiveEntry extends DirectiveEntry {
suffix: string;
}
export interface DefaultSuffixDirectiveEntry extends DirectiveEntry {
suffix: null;
}
export declare function isNonDefaultDirectiveSuffix(entry: DirectiveEntry): entry is NonDefaultSuffixDirectiveEntry;
export declare function isDefaultDirectiveSuffix(entry: DirectiveEntry): entry is DefaultSuffixDirectiveEntry;
type DirectiveEntries = Record<string, DirectiveEntry[]>;

@@ -43,3 +51,3 @@ interface DirectiveArgs {

}
interface DirectiveCallback {
export interface DirectiveCallback {
(args: DirectiveArgs): VNode<any> | null | void;

@@ -72,3 +80,3 @@ }

* ( { directives: { alert }, element, evaluate } ) => {
* const defaultEntry = alert.find( entry => entry.suffix === 'default' );
* const defaultEntry = alert.find( isDefaultDirectiveSuffix );
* element.props.onclick = () => { alert( evaluate( defaultEntry ) ); }

@@ -92,3 +100,3 @@ * }

* Note that, in the previous example, the directive callback gets the path
* value (`state.alert`) from the directive entry with suffix `default`. A
* value (`state.alert`) from the directive entry with suffix `null`. A
* custom suffix can also be specified by appending `--` to the directive

@@ -95,0 +103,0 @@ * attribute, followed by the suffix, like in the following HTML snippet:

@@ -5,2 +5,9 @@ /**

import { type EffectCallback, type Inputs } from 'preact/hooks';
declare global {
interface Window {
scheduler?: {
readonly yield?: () => Promise<void>;
};
}
}
/**

@@ -7,0 +14,0 @@ * Returns a promise that resolves after yielding to main.

@@ -0,1 +1,2 @@

/* wp:polyfill */
"use strict";

@@ -80,5 +81,3 @@

}) => {
directives[`on-${type}`].filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
directives[`on-${type}`].filter(_hooks2.isNonDefaultDirectiveSuffix).forEach(entry => {
const eventName = entry.suffix.split('--', 1)[0];

@@ -106,5 +105,3 @@ (0, _utils.useInit)(() => {

}) => {
directives[`on-async-${type}`].filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
directives[`on-async-${type}`].filter(_hooks2.isNonDefaultDirectiveSuffix).forEach(entry => {
const eventName = entry.suffix.split('--', 1)[0];

@@ -139,5 +136,3 @@ (0, _utils.useInit)(() => {

} = inheritedContext;
const defaultEntry = context.find(({
suffix
}) => suffix === 'default');
const defaultEntry = context.find(_hooks2.isDefaultDirectiveSuffix);
const {

@@ -266,5 +261,3 @@ client: inheritedClient,

const events = new Map();
on.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
on.filter(_hooks2.isNonDefaultDirectiveSuffix).forEach(entry => {
const event = entry.suffix.split('--')[0];

@@ -318,5 +311,3 @@ if (!events.has(event)) {

const events = new Map();
onAsync.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
onAsync.filter(_hooks2.isNonDefaultDirectiveSuffix).forEach(entry => {
const event = entry.suffix.split('--')[0];

@@ -360,5 +351,3 @@ if (!events.has(event)) {

}) => {
classNames.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
classNames.filter(_hooks2.isNonDefaultDirectiveSuffix).forEach(entry => {
const className = entry.suffix;

@@ -396,5 +385,3 @@ const result = evaluate(entry);

}) => {
style.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
style.filter(_hooks2.isNonDefaultDirectiveSuffix).forEach(entry => {
const styleProp = entry.suffix;

@@ -434,5 +421,3 @@ const result = evaluate(entry);

}) => {
bind.filter(({
suffix
}) => suffix !== 'default').forEach(entry => {
bind.filter(_hooks2.isNonDefaultDirectiveSuffix).forEach(entry => {
const attribute = entry.suffix;

@@ -521,5 +506,3 @@ const result = evaluate(entry);

}) => {
const entry = text.find(({
suffix
}) => suffix === 'default');
const entry = text.find(_hooks2.isDefaultDirectiveSuffix);
if (!entry) {

@@ -566,8 +549,7 @@ element.props.children = null;

const {
namespace,
suffix
namespace
} = entry;
const list = evaluate(entry);
const itemProp = (0, _hooks2.isNonDefaultDirectiveSuffix)(entry) ? (0, _utils.kebabToCamelCase)(entry.suffix) : 'item';
return list.map(item => {
const itemProp = suffix === 'default' ? 'item' : (0, _utils.kebabToCamelCase)(suffix);
const itemContext = (0, _proxies.proxifyContext)((0, _proxies.proxifyState)(namespace, {}), inheritedValue.client[namespace]);

@@ -574,0 +556,0 @@ const mergedContext = {

@@ -7,2 +7,4 @@ "use strict";

exports.getEvaluate = exports.directive = void 0;
exports.isDefaultDirectiveSuffix = isDefaultDirectiveSuffix;
exports.isNonDefaultDirectiveSuffix = isNonDefaultDirectiveSuffix;
var _preact = require("preact");

@@ -24,2 +26,8 @@ var _hooks = require("preact/hooks");

function isNonDefaultDirectiveSuffix(entry) {
return entry.suffix !== null;
}
function isDefaultDirectiveSuffix(entry) {
return entry.suffix === null;
}
// Main context.

@@ -43,3 +51,3 @@ const context = (0, _preact.createContext)({

* ( { directives: { alert }, element, evaluate } ) => {
* const defaultEntry = alert.find( entry => entry.suffix === 'default' );
* const defaultEntry = alert.find( isDefaultDirectiveSuffix );
* element.props.onclick = () => { alert( evaluate( defaultEntry ) ); }

@@ -63,3 +71,3 @@ * }

* Note that, in the previous example, the directive callback gets the path
* value (`state.alert`) from the directive entry with suffix `default`. A
* value (`state.alert`) from the directive entry with suffix `null`. A
* custom suffix can also be specified by appending `--` to the directive

@@ -242,5 +250,3 @@ * attribute, followed by the suffix, like in the following HTML snippet:

if (directives.key) {
vnode.key = directives.key.find(({
suffix
}) => suffix === 'default').value;
vnode.key = directives.key.find(isDefaultDirectiveSuffix).value;
}

@@ -247,0 +253,0 @@ delete props.__directives;

@@ -0,1 +1,2 @@

/* wp:polyfill */
"use strict";

@@ -2,0 +3,0 @@

@@ -0,1 +1,2 @@

/* wp:polyfill */
"use strict";

@@ -2,0 +3,0 @@

@@ -0,1 +1,2 @@

/* wp:polyfill */
"use strict";

@@ -255,39 +256,43 @@

const deepMergeRecursive = (target, source, override = true) => {
if ((0, _utils.isPlainObject)(target) && (0, _utils.isPlainObject)(source)) {
let hasNewKeys = false;
for (const key in source) {
const isNew = !(key in target);
hasNewKeys = hasNewKeys || isNew;
const desc = Object.getOwnPropertyDescriptor(source, key);
if (typeof desc?.get === 'function' || typeof desc?.set === 'function') {
if (override || isNew) {
Object.defineProperty(target, key, {
...desc,
configurable: true,
enumerable: true
});
const proxy = (0, _registry.getProxyFromObject)(target);
if (desc?.get && proxy && hasPropSignal(proxy, key)) {
const propSignal = getPropSignal(proxy, key);
propSignal.setGetter(desc.get);
}
if (!((0, _utils.isPlainObject)(target) && (0, _utils.isPlainObject)(source))) {
return;
}
let hasNewKeys = false;
for (const key in source) {
const isNew = !(key in target);
hasNewKeys = hasNewKeys || isNew;
const desc = Object.getOwnPropertyDescriptor(source, key);
const proxy = (0, _registry.getProxyFromObject)(target);
const propSignal = !!proxy && hasPropSignal(proxy, key) && getPropSignal(proxy, key);
if (typeof desc.get === 'function' || typeof desc.set === 'function') {
if (override || isNew) {
Object.defineProperty(target, key, {
...desc,
configurable: true,
enumerable: true
});
if (desc.get && propSignal) {
propSignal.setGetter(desc.get);
}
} else if ((0, _utils.isPlainObject)(source[key])) {
if (isNew) {
target[key] = {};
}
} else if ((0, _utils.isPlainObject)(source[key])) {
if (isNew || override && !(0, _utils.isPlainObject)(target[key])) {
target[key] = {};
if (propSignal) {
propSignal.setValue(target[key]);
}
}
if ((0, _utils.isPlainObject)(target[key])) {
deepMergeRecursive(target[key], source[key], override);
} else if (override || isNew) {
Object.defineProperty(target, key, desc);
const proxy = (0, _registry.getProxyFromObject)(target);
if (desc?.value && proxy && hasPropSignal(proxy, key)) {
const propSignal = getPropSignal(proxy, key);
propSignal.setValue(desc.value);
}
}
} else if (override || isNew) {
Object.defineProperty(target, key, desc);
if (propSignal) {
propSignal.setValue(desc.value);
}
}
if (hasNewKeys && objToIterable.has(target)) {
objToIterable.get(target).value++;
}
}
if (hasNewKeys && objToIterable.has(target)) {
objToIterable.get(target).value++;
}
};

@@ -294,0 +299,0 @@

@@ -0,1 +1,2 @@

/* wp:polyfill */
"use strict";

@@ -56,5 +57,4 @@

*/
const splitTask = () => {
const splitTask = exports.splitTask = typeof window.scheduler?.yield === 'function' ? window.scheduler.yield.bind(window.scheduler) : () => {
return new Promise(resolve => {
// TODO: Use scheduler.yield() when available.
setTimeout(resolve, 0);

@@ -76,3 +76,2 @@ });

*/
exports.splitTask = splitTask;
function createFlusher(compute, notify) {

@@ -79,0 +78,0 @@ let flush = () => undefined;

@@ -142,7 +142,7 @@ "use strict";

const prefix = directiveMatch[1] || '';
const suffix = directiveMatch[2] || 'default';
const suffix = directiveMatch[2] || null;
obj[prefix] = obj[prefix] || [];
obj[prefix].push({
namespace: ns !== null && ns !== void 0 ? ns : currentNamespace(),
value,
value: value,
suffix

@@ -153,4 +153,2 @@ });

}
// @ts-expect-error Fixed in upcoming preact release https://github.com/preactjs/preact/pull/4334
if (localName === 'template') {

@@ -157,0 +155,0 @@ props.content = [...elementNode.content.childNodes].map(childNode => toVdom(childNode));

@@ -5,2 +5,13 @@ <!-- Learn how to maintain this file at https://github.com/WordPress/gutenberg/tree/HEAD/packages#maintaining-changelogs. -->

## 6.10.0 (2024-10-16)
### Internal
- Upgrade preact libraries [#66008](https://github.com/WordPress/gutenberg/pull/66008).
### Bug Fixes
- Fix an issue where "default" could not be used as a directive suffix ([#65815](https://github.com/WordPress/gutenberg/pull/65815)).
- Correctly handle lazily added, deeply nested properties with `deepMerge()` ([#65465](https://github.com/WordPress/gutenberg/pull/65465)).
## 6.9.0 (2024-10-03)

@@ -7,0 +18,0 @@

{
"name": "@wordpress/interactivity",
"version": "6.9.0",
"version": "6.10.0",
"description": "Package that provides a standard and simple way to handle the frontend interactivity of Gutenberg blocks.",

@@ -34,4 +34,4 @@ "author": "The WordPress Contributors",

"dependencies": {
"@preact/signals": "^1.2.2",
"preact": "^10.19.3"
"@preact/signals": "^1.3.0",
"preact": "^10.24.2"
},

@@ -41,3 +41,3 @@ "publishConfig": {

},
"gitHead": "2e5495c635910cb34bfaca3c6258d2e989f66214"
"gitHead": "ab34a7ac935fd1478eac63b596242d83270897ee"
}

@@ -303,46 +303,53 @@ /**

) => {
if ( isPlainObject( target ) && isPlainObject( source ) ) {
let hasNewKeys = false;
for ( const key in source ) {
const isNew = ! ( key in target );
hasNewKeys = hasNewKeys || isNew;
if ( ! ( isPlainObject( target ) && isPlainObject( source ) ) ) {
return;
}
const desc = Object.getOwnPropertyDescriptor( source, key );
if (
typeof desc?.get === 'function' ||
typeof desc?.set === 'function'
) {
if ( override || isNew ) {
Object.defineProperty( target, key, {
...desc,
configurable: true,
enumerable: true,
} );
let hasNewKeys = false;
const proxy = getProxyFromObject( target );
if ( desc?.get && proxy && hasPropSignal( proxy, key ) ) {
const propSignal = getPropSignal( proxy, key );
propSignal.setGetter( desc.get );
}
}
} else if ( isPlainObject( source[ key ] ) ) {
if ( isNew ) {
target[ key ] = {};
}
for ( const key in source ) {
const isNew = ! ( key in target );
hasNewKeys = hasNewKeys || isNew;
deepMergeRecursive( target[ key ], source[ key ], override );
} else if ( override || isNew ) {
Object.defineProperty( target, key, desc! );
const desc = Object.getOwnPropertyDescriptor( source, key )!;
const proxy = getProxyFromObject( target );
const propSignal =
!! proxy &&
hasPropSignal( proxy, key ) &&
getPropSignal( proxy, key );
const proxy = getProxyFromObject( target );
if ( desc?.value && proxy && hasPropSignal( proxy, key ) ) {
const propSignal = getPropSignal( proxy, key );
propSignal.setValue( desc.value );
if (
typeof desc.get === 'function' ||
typeof desc.set === 'function'
) {
if ( override || isNew ) {
Object.defineProperty( target, key, {
...desc,
configurable: true,
enumerable: true,
} );
if ( desc.get && propSignal ) {
propSignal.setGetter( desc.get );
}
}
} else if ( isPlainObject( source[ key ] ) ) {
if ( isNew || ( override && ! isPlainObject( target[ key ] ) ) ) {
target[ key ] = {};
if ( propSignal ) {
propSignal.setValue( target[ key ] );
}
}
if ( isPlainObject( target[ key ] ) ) {
deepMergeRecursive( target[ key ], source[ key ], override );
}
} else if ( override || isNew ) {
Object.defineProperty( target, key, desc );
if ( propSignal ) {
propSignal.setValue( desc.value );
}
}
}
if ( hasNewKeys && objToIterable.has( target ) ) {
objToIterable.get( target )!.value++;
}
if ( hasNewKeys && objToIterable.has( target ) ) {
objToIterable.get( target )!.value++;
}

@@ -349,0 +356,0 @@ };

@@ -9,3 +9,3 @@ /**

*/
import { proxifyContext, proxifyState } from '../';
import { proxifyContext, proxifyState, deepMerge } from '../';

@@ -281,2 +281,62 @@ describe( 'Interactivity API', () => {

} );
it( 'should handle deeply nested properties that are initially undefined', () => {
const fallback: any = proxifyContext(
proxifyState( 'test', {} ),
{}
);
const context: any = proxifyContext(
proxifyState( 'test', {} ),
fallback
);
let deepValue: any;
const spy = jest.fn( () => {
deepValue = context.a?.b?.c?.d;
} );
effect( spy );
// Initial call, the deep value is undefined
expect( spy ).toHaveBeenCalledTimes( 1 );
expect( deepValue ).toBeUndefined();
// Add a deeply nested object to the context
context.a = { b: { c: { d: 'test value' } } };
// The effect should be called again
expect( spy ).toHaveBeenCalledTimes( 2 );
expect( deepValue ).toBe( 'test value' );
// Reading the value directly should also work
expect( context.a.b.c.d ).toBe( 'test value' );
} );
it( 'should handle deeply nested properties that are initially undefined and merged with deepMerge', () => {
const fallbackState = proxifyState( 'test', {} );
const fallback: any = proxifyContext( fallbackState, {} );
const contextState = proxifyState( 'test', {} );
const context: any = proxifyContext( contextState, fallback );
let deepValue: any;
const spy = jest.fn( () => {
deepValue = context.a?.b?.c?.d;
} );
effect( spy );
// Initial call, the deep value is undefined
expect( spy ).toHaveBeenCalledTimes( 1 );
expect( deepValue ).toBeUndefined();
// Use deepMerge to add a deeply nested object to the context
deepMerge( contextState, {
a: { b: { c: { d: 'test value' } } },
} );
// The effect should be called again
expect( spy ).toHaveBeenCalledTimes( 2 );
expect( deepValue ).toBe( 'test value' );
// Reading the value directly should also work
expect( context.a.b.c.d ).toBe( 'test value' );
} );
} );

@@ -283,0 +343,0 @@

@@ -392,3 +392,76 @@ /* eslint-disable eslint-comments/disable-enable-pair */

} );
it( 'should handle deeply nested properties that are initially undefined', () => {
const target: any = proxifyState( 'test', {} );
let deepValue: any;
const spy = jest.fn( () => {
deepValue = target.a?.b?.c?.d;
} );
effect( spy );
// Initial call, the deep value is undefined
expect( spy ).toHaveBeenCalledTimes( 1 );
expect( deepValue ).toBeUndefined();
// Use deepMerge to add a deeply nested object to the target
deepMerge( target, { a: { b: { c: { d: 'test value' } } } } );
// The effect should be called again
expect( spy ).toHaveBeenCalledTimes( 2 );
expect( deepValue ).toBe( 'test value' );
// Reading the value directly should also work
expect( target.a.b.c.d ).toBe( 'test value' );
} );
it( 'should overwrite values that become objects', () => {
const target: any = proxifyState( 'test', { message: 'hello' } );
let message: any;
const spy = jest.fn( () => ( message = target.message ) );
effect( spy );
expect( spy ).toHaveBeenCalledTimes( 1 );
expect( message ).toBe( 'hello' );
deepMerge( target, {
message: { content: 'hello', fontStyle: 'italic' },
} );
expect( spy ).toHaveBeenCalledTimes( 2 );
expect( message ).toEqual( {
content: 'hello',
fontStyle: 'italic',
} );
expect( target.message ).toEqual( {
content: 'hello',
fontStyle: 'italic',
} );
} );
it( 'should not overwrite values that become objects if `override` is false', () => {
const target: any = proxifyState( 'test', { message: 'hello' } );
let message: any;
const spy = jest.fn( () => ( message = target.message ) );
effect( spy );
expect( spy ).toHaveBeenCalledTimes( 1 );
expect( message ).toBe( 'hello' );
deepMerge(
target,
{ message: { content: 'hello', fontStyle: 'italic' } },
false
);
expect( spy ).toHaveBeenCalledTimes( 1 );
expect( message ).toBe( 'hello' );
expect( target.message ).toBe( 'hello' );
expect( target.message.content ).toBeUndefined();
expect( target.message.fontStyle ).toBeUndefined();
} );
} );
} );

@@ -25,2 +25,10 @@ /**

declare global {
interface Window {
scheduler?: {
readonly yield?: () => Promise< void >;
};
}
}
/**

@@ -52,8 +60,10 @@ * Executes a callback function after the next frame is rendered.

*/
export const splitTask = () => {
return new Promise( ( resolve ) => {
// TODO: Use scheduler.yield() when available.
setTimeout( resolve, 0 );
} );
};
export const splitTask =
typeof window.scheduler?.yield === 'function'
? window.scheduler.yield.bind( window.scheduler )
: () => {
return new Promise( ( resolve ) => {
setTimeout( resolve, 0 );
} );
};

@@ -72,5 +82,5 @@ /**

*/
function createFlusher( compute: () => unknown, notify: () => void ): Flusher {
function createFlusher( compute: () => void, notify: () => void ): Flusher {
let flush: () => void = () => undefined;
const dispose = effect( function ( this: any ) {
const dispose = effect( function ( this: any ): void {
flush = this.c.bind( this );

@@ -77,0 +87,0 @@ this.x = compute;

@@ -10,2 +10,3 @@ /**

import { warn } from './utils';
import { type DirectiveEntry } from './hooks';

@@ -143,25 +144,23 @@ const ignoreAttr = `data-${ p }-ignore`;

if ( directives.length ) {
props.__directives = directives.reduce(
( obj, [ name, ns, value ] ) => {
const directiveMatch = directiveParser.exec( name );
if ( directiveMatch === null ) {
warn( `Found malformed directive name: ${ name }.` );
return obj;
}
const prefix = directiveMatch[ 1 ] || '';
const suffix = directiveMatch[ 2 ] || 'default';
props.__directives = directives.reduce<
Record< string, Array< DirectiveEntry > >
>( ( obj, [ name, ns, value ] ) => {
const directiveMatch = directiveParser.exec( name );
if ( directiveMatch === null ) {
warn( `Found malformed directive name: ${ name }.` );
return obj;
}
const prefix = directiveMatch[ 1 ] || '';
const suffix = directiveMatch[ 2 ] || null;
obj[ prefix ] = obj[ prefix ] || [];
obj[ prefix ].push( {
namespace: ns ?? currentNamespace(),
value,
suffix,
} );
return obj;
},
{}
);
obj[ prefix ] = obj[ prefix ] || [];
obj[ prefix ].push( {
namespace: ns ?? currentNamespace()!,
value: value as DirectiveEntry[ 'value' ],
suffix,
} );
return obj;
}, {} );
}
// @ts-expect-error Fixed in upcoming preact release https://github.com/preactjs/preact/pull/4334
if ( localName === 'template' ) {

@@ -168,0 +167,0 @@ props.content = [

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc