solid-js 1.4.1 → 1.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/html/dist/html.js CHANGED
@@ -177,15 +177,15 @@ const attrName = "[ " + spaces + "]+" + almostEverything;
177
177
  const tagName = "<([A-Za-z$#]+[A-Za-z0-9:_-]*)((?:";
178
178
  const attrPartials = "(?:\\s*=\\s*(?:'[^']*?'|\"[^\"]*?\"|\\([^)]*?\\)|<[^>]*?>|" + almostEverything + "))?)";
179
179
  const attrSeeker = new RegExp(tagName + attrName + attrPartials + "+)([ " + spaces + "]*/?>)", "g");
180
- const findAttributes = new RegExp("(" + attrName + "\\s*=\\s*)(['\"(]?)" + "<!--#-->" + "(['\")]?)", "gi");
180
+ const findAttributes = new RegExp("(" + attrName + "\\s*=\\s*)(<!--#-->|['\"(]([\\w\\s]*<!--#-->[\\w\\s]*)*['\")])", "gi");
181
181
  const selfClosing = new RegExp(tagName + attrName + attrPartials + "*)([ " + spaces + "]*/>)", "g");
182
182
  const marker = "<!--#-->";
183
183
  const reservedNameSpaces = new Set(["class", "on", "oncapture", "style", "use", "prop", "attr"]);
184
184
  function attrReplacer($0, $1, $2, $3) {
185
185
  return "<" + $1 + $2.replace(findAttributes, replaceAttributes) + $3;
186
186
  }
187
- function replaceAttributes($0, $1, $2, $3) {
188
- return $1 + ($2 || '"') + "###" + ($3 || '"');
187
+ function replaceAttributes($0, $1, $2) {
188
+ return $1 + ($2[0] === '"' || $2[0] === "'" ? $2.replace(/<!--#-->/g, "###") : '"###"');
189
189
  }
190
190
  function fullClosing($0, $1, $2) {
191
191
  return VOID_ELEMENTS.test($1) ? $0 : "<" + $1 + $2 + "></" + $1 + ">";
@@ -234,9 +234,8 @@ function createHTML(r, {
234
234
  cache.set(statics, templates);
235
235
  return templates;
236
236
  }
237
- function parseKeyValue(tag, name, isSVG, isCE, options) {
238
- let count = options.counter++,
239
- expr = `!doNotWrap ? exprs[${count}]() : exprs[${count}]`,
237
+ function parseKeyValue(tag, name, value, isSVG, isCE, options) {
238
+ let expr = value === "###" ? `!doNotWrap ? exprs[${options.counter}]() : exprs[${options.counter++}]` : value.split("###").map((v, i) => i ? ` + (typeof exprs[${options.counter}] === "function" ? exprs[${options.counter}]() : exprs[${options.counter++}]) + "${v}"` : `"${v}"`).join(""),
240
239
  parts,
241
240
  namespace;
242
241
  if ((parts = name.split(":")) && parts[1] && reservedNameSpaces.has(parts[0])) {
@@ -261,7 +260,7 @@ function createHTML(r, {
261
260
  if (ns) options.exprs.push(`r.setAttributeNS(${tag},"${ns}","${name}",${expr})`);else options.exprs.push(`r.setAttribute(${tag},"${r.Aliases[name] || name}",${expr})`);
262
261
  }
263
262
  }
264
- function parseAttribute(tag, name, isSVG, isCE, options) {
263
+ function parseAttribute(tag, name, value, isSVG, isCE, options) {
265
264
  if (name.slice(0, 2) === "on") {
266
265
  if (!name.includes(":")) {
267
266
  const lc = name.slice(2).toLowerCase();
@@ -279,9 +278,18 @@ function createHTML(r, {
279
278
  exprs: []
280
279
  }),
281
280
  count = options.counter;
282
- parseKeyValue(tag, name, isSVG, isCE, childOptions);
283
- options.decl.push(`_fn${count} = doNotWrap => {\n${childOptions.exprs.join(";\n")};\n}`);
284
- options.exprs.push(`typeof exprs[${count}] === "function" ? r.effect(_fn${count}) : _fn${count}(true)`);
281
+ parseKeyValue(tag, name, value, isSVG, isCE, childOptions);
282
+ options.decl.push(`_fn${count} = (${value === "###" ? "doNotWrap" : ""}) => {\n${childOptions.exprs.join(";\n")};\n}`);
283
+ if (value === "###") {
284
+ options.exprs.push(`typeof exprs[${count}] === "function" ? r.effect(_fn${count}) : _fn${count}(true)`);
285
+ } else {
286
+ let check = "";
287
+ for (let i = count; i < childOptions.counter; i++) {
288
+ i !== count && (check += " || ");
289
+ check += `typeof exprs[${i}] === "function"`;
290
+ }
291
+ options.exprs.push(check + ` ? r.effect(_fn${count}) : _fn${count}()`);
292
+ }
285
293
  options.counter = childOptions.counter;
286
294
  options.wrap = false;
287
295
  }
@@ -320,6 +328,7 @@ function createHTML(r, {
320
328
  }
321
329
  options.counter = childOptions.counter;
322
330
  options.templateId = childOptions.templateId;
331
+ options.hasCustomElement = options.hasCustomElement || childOptions.hasCustomElement;
323
332
  }
324
333
  function processComponentProps(propGroups) {
325
334
  let result = [];
@@ -412,16 +421,19 @@ function createHTML(r, {
412
421
  options.exprs.push(`return [${parts.join(", \n")}]`);
413
422
  } else if (node.type === "tag") {
414
423
  const tag = `_$el${uuid++}`;
415
- options.decl.push(!options.decl.length ? `const ${tag} = tmpls[${options.templateId}].content.firstChild.cloneNode(true)` : `${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
424
+ const topDecl = !options.decl.length;
425
+ const templateId = options.templateId;
426
+ options.decl.push(topDecl ? "" : `${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
416
427
  const keys = Object.keys(node.attrs);
417
428
  const isSVG = r.SVGElements.has(node.name);
418
429
  const isCE = node.name.includes("-");
430
+ options.hasCustomElement = isCE;
419
431
  for (let i = 0; i < keys.length; i++) {
420
432
  const name = keys[i],
421
433
  value = node.attrs[name];
422
- if (value === "###") {
434
+ if (value.includes("###")) {
423
435
  delete node.attrs[name];
424
- parseAttribute(tag, name, isSVG, isCE, options);
436
+ parseAttribute(tag, name, value, isSVG, isCE, options);
425
437
  } else if (name === "###") {
426
438
  delete node.attrs[name];
427
439
  options.exprs.push(`r.spread(${tag},exprs[${options.counter++}],${isSVG},${!!node.children.length})`);
@@ -430,17 +442,22 @@ function createHTML(r, {
430
442
  options.path = tag;
431
443
  options.first = false;
432
444
  processChildren(node, options);
445
+ if (topDecl) {
446
+ options.decl[0] = options.hasCustomElement ? `const ${tag} = document.importNode(tmpls[${templateId}].content.firstChild, true)` : `const ${tag} = tmpls[${templateId}].content.firstChild.cloneNode(true)`;
447
+ }
433
448
  } else if (node.type === "text") {
434
449
  const tag = `_$el${uuid++}`;
435
450
  options.decl.push(`${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
436
451
  options.path = tag;
437
452
  options.first = false;
438
- } else if (node.type === "comment" && node.content === "#") {
453
+ } else if (node.type === "comment") {
439
454
  const tag = `_$el${uuid++}`;
440
455
  options.decl.push(`${tag} = ${options.path}.${options.first ? "firstChild" : "nextSibling"}`);
441
- if (options.multi) {
442
- options.exprs.push(`r.insert(${options.parent}, exprs[${options.counter++}], ${tag})`);
443
- } else options.exprs.push(`r.insert(${options.parent}, exprs[${options.counter++}])`);
456
+ if (node.content === "#") {
457
+ if (options.multi) {
458
+ options.exprs.push(`r.insert(${options.parent}, exprs[${options.counter++}], ${tag})`);
459
+ } else options.exprs.push(`r.insert(${options.parent}, exprs[${options.counter++}])`);
460
+ }
444
461
  options.path = tag;
445
462
  options.first = false;
446
463
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "solid-js",
3
3
  "description": "A declarative JavaScript library for building user interfaces.",
4
- "version": "1.4.1",
4
+ "version": "1.4.4",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -151,5 +151,5 @@
151
151
  "compiler",
152
152
  "performance"
153
153
  ],
154
- "gitHead": "be6623d10d11fb28743a074c31e785c18e95bd25"
154
+ "gitHead": "9f1de6b3cea905aa0857789a0e4738cae73cb1b1"
155
155
  }
package/store/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This submodules contains the means for handling deeps nested reactivity. It provides 2 main primitives `createStore` and `createMutable` which leverage proxies to create dynamic nested reactive structures.
4
4
 
5
- This also contains helper methods `produce` and `reconcile` which augment the behavior of the store setter method to allow for localized mutationa and data diffing.
5
+ This also contains helper methods `produce` and `reconcile` which augment the behavior of the store setter method to allow for localized mutation and data diffing.
6
6
 
7
7
  For full documentation, check out the [website](https://www.solidjs.com/docs/latest/api).
8
8
 
@@ -20,4 +20,4 @@ const [store, setStore] = createStore({
20
20
 
21
21
  // update store.user.firstName
22
22
  setStore("user", "firstName", "Will");
23
- ```
23
+ ```
@@ -31,7 +31,8 @@ function wrap$1(value, name) {
31
31
  return p;
32
32
  }
33
33
  function isWrappable(obj) {
34
- return obj != null && typeof obj === "object" && (obj[solidJs.$PROXY] || !obj.__proto__ || obj.__proto__ === Object.prototype || Array.isArray(obj));
34
+ let proto;
35
+ return obj != null && typeof obj === "object" && (obj[solidJs.$PROXY] || !(proto = Object.getPrototypeOf(obj)) || proto === Object.prototype || Array.isArray(obj));
35
36
  }
36
37
  function unwrap(item, set = new Set()) {
37
38
  let result, unwrapped, v, prop;
@@ -143,14 +144,16 @@ function mergeStoreNode(state, value) {
143
144
  function updateArray(current, next) {
144
145
  if (typeof next === "function") next = next(current);
145
146
  next = unwrap(next);
146
- if (current === next) return;
147
- let i = 0,
148
- len = next.length;
149
- for (; i < len; i++) {
150
- const value = next[i];
151
- if (current[i] !== value) setProperty(current, i, value);
152
- }
153
- setProperty(current, "length", len);
147
+ if (Array.isArray(next)) {
148
+ if (current === next) return;
149
+ let i = 0,
150
+ len = next.length;
151
+ for (; i < len; i++) {
152
+ const value = next[i];
153
+ if (current[i] !== value) setProperty(current, i, value);
154
+ }
155
+ setProperty(current, "length", len);
156
+ } else mergeStoreNode(current, next);
154
157
  }
155
158
  function updatePath(current, path, traversed = []) {
156
159
  let part,
@@ -291,11 +294,15 @@ function modifyMutable(state, modifier) {
291
294
  solidJs.batch(() => modifier(unwrap(state)));
292
295
  }
293
296
 
297
+ const $ROOT = Symbol("store-root");
294
298
  function applyState(target, parent, property, merge, key) {
295
299
  const previous = parent[property];
296
300
  if (target === previous) return;
297
301
  if (!isWrappable(target) || !isWrappable(previous) || key && target[key] !== previous[key]) {
298
- target !== previous && setProperty(parent, property, target);
302
+ if (target !== previous) {
303
+ if (property === $ROOT) return target;
304
+ setProperty(parent, property, target);
305
+ }
299
306
  return;
300
307
  }
301
308
  if (Array.isArray(target)) {
@@ -367,17 +374,19 @@ function reconcile(value, options = {}) {
367
374
  v = unwrap(value);
368
375
  return state => {
369
376
  if (!isWrappable(state) || !isWrappable(v)) return v;
370
- solidJs.batch(() => applyState(v, {
371
- state
372
- }, "state", merge, key));
373
- return state;
377
+ const res = applyState(v, {
378
+ [$ROOT]: state
379
+ }, $ROOT, merge, key);
380
+ return res === undefined ? state : res;
374
381
  };
375
382
  }
383
+ const producers = new WeakMap();
376
384
  const setterTraps = {
377
385
  get(target, property) {
378
386
  if (property === $RAW) return target;
379
387
  const value = target[property];
380
- return isWrappable(value) ? new Proxy(value, setterTraps) : value;
388
+ let proxy;
389
+ return isWrappable(value) ? producers.get(value) || (producers.set(value, proxy = new Proxy(value, setterTraps)), proxy) : value;
381
390
  },
382
391
  set(target, property, value) {
383
392
  setProperty(target, property, unwrap(value));
@@ -390,7 +399,13 @@ const setterTraps = {
390
399
  };
391
400
  function produce(fn) {
392
401
  return state => {
393
- if (isWrappable(state)) fn(new Proxy(state, setterTraps));
402
+ if (isWrappable(state)) {
403
+ let proxy;
404
+ if (!(proxy = producers.get(state))) {
405
+ producers.set(state, proxy = new Proxy(state, setterTraps));
406
+ }
407
+ fn(proxy);
408
+ }
394
409
  return state;
395
410
  };
396
411
  }
package/store/dist/dev.js CHANGED
@@ -27,7 +27,8 @@ function wrap$1(value, name) {
27
27
  return p;
28
28
  }
29
29
  function isWrappable(obj) {
30
- return obj != null && typeof obj === "object" && (obj[$PROXY] || !obj.__proto__ || obj.__proto__ === Object.prototype || Array.isArray(obj));
30
+ let proto;
31
+ return obj != null && typeof obj === "object" && (obj[$PROXY] || !(proto = Object.getPrototypeOf(obj)) || proto === Object.prototype || Array.isArray(obj));
31
32
  }
32
33
  function unwrap(item, set = new Set()) {
33
34
  let result, unwrapped, v, prop;
@@ -139,14 +140,16 @@ function mergeStoreNode(state, value) {
139
140
  function updateArray(current, next) {
140
141
  if (typeof next === "function") next = next(current);
141
142
  next = unwrap(next);
142
- if (current === next) return;
143
- let i = 0,
144
- len = next.length;
145
- for (; i < len; i++) {
146
- const value = next[i];
147
- if (current[i] !== value) setProperty(current, i, value);
148
- }
149
- setProperty(current, "length", len);
143
+ if (Array.isArray(next)) {
144
+ if (current === next) return;
145
+ let i = 0,
146
+ len = next.length;
147
+ for (; i < len; i++) {
148
+ const value = next[i];
149
+ if (current[i] !== value) setProperty(current, i, value);
150
+ }
151
+ setProperty(current, "length", len);
152
+ } else mergeStoreNode(current, next);
150
153
  }
151
154
  function updatePath(current, path, traversed = []) {
152
155
  let part,
@@ -287,11 +290,15 @@ function modifyMutable(state, modifier) {
287
290
  batch(() => modifier(unwrap(state)));
288
291
  }
289
292
 
293
+ const $ROOT = Symbol("store-root");
290
294
  function applyState(target, parent, property, merge, key) {
291
295
  const previous = parent[property];
292
296
  if (target === previous) return;
293
297
  if (!isWrappable(target) || !isWrappable(previous) || key && target[key] !== previous[key]) {
294
- target !== previous && setProperty(parent, property, target);
298
+ if (target !== previous) {
299
+ if (property === $ROOT) return target;
300
+ setProperty(parent, property, target);
301
+ }
295
302
  return;
296
303
  }
297
304
  if (Array.isArray(target)) {
@@ -363,17 +370,19 @@ function reconcile(value, options = {}) {
363
370
  v = unwrap(value);
364
371
  return state => {
365
372
  if (!isWrappable(state) || !isWrappable(v)) return v;
366
- batch(() => applyState(v, {
367
- state
368
- }, "state", merge, key));
369
- return state;
373
+ const res = applyState(v, {
374
+ [$ROOT]: state
375
+ }, $ROOT, merge, key);
376
+ return res === undefined ? state : res;
370
377
  };
371
378
  }
379
+ const producers = new WeakMap();
372
380
  const setterTraps = {
373
381
  get(target, property) {
374
382
  if (property === $RAW) return target;
375
383
  const value = target[property];
376
- return isWrappable(value) ? new Proxy(value, setterTraps) : value;
384
+ let proxy;
385
+ return isWrappable(value) ? producers.get(value) || (producers.set(value, proxy = new Proxy(value, setterTraps)), proxy) : value;
377
386
  },
378
387
  set(target, property, value) {
379
388
  setProperty(target, property, unwrap(value));
@@ -386,7 +395,13 @@ const setterTraps = {
386
395
  };
387
396
  function produce(fn) {
388
397
  return state => {
389
- if (isWrappable(state)) fn(new Proxy(state, setterTraps));
398
+ if (isWrappable(state)) {
399
+ let proxy;
400
+ if (!(proxy = producers.get(state))) {
401
+ producers.set(state, proxy = new Proxy(state, setterTraps));
402
+ }
403
+ fn(proxy);
404
+ }
390
405
  return state;
391
406
  };
392
407
  }
@@ -4,7 +4,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  const $RAW = Symbol("state-raw");
6
6
  function isWrappable(obj) {
7
- return obj != null && typeof obj === "object" && (obj.__proto__ === Object.prototype || Array.isArray(obj));
7
+ return obj != null && typeof obj === "object" && (Object.getPrototypeOf(obj) === Object.prototype || Array.isArray(obj));
8
8
  }
9
9
  function unwrap(item) {
10
10
  return item;
@@ -22,6 +22,19 @@ function mergeStoreNode(state, value, force) {
22
22
  setProperty(state, key, value[key], force);
23
23
  }
24
24
  }
25
+ function updateArray(current, next) {
26
+ if (typeof next === "function") next = next(current);
27
+ if (Array.isArray(next)) {
28
+ if (current === next) return;
29
+ let i = 0,
30
+ len = next.length;
31
+ for (; i < len; i++) {
32
+ const value = next[i];
33
+ if (current[i] !== value) setProperty(current, i, value);
34
+ }
35
+ setProperty(current, "length", len);
36
+ } else mergeStoreNode(current, next);
37
+ }
25
38
  function updatePath(current, path, traversed = []) {
26
39
  let part,
27
40
  next = current;
@@ -67,8 +80,9 @@ function updatePath(current, path, traversed = []) {
67
80
  } else setProperty(current, part, value);
68
81
  }
69
82
  function createStore(state) {
83
+ const isArray = Array.isArray(state);
70
84
  function setStore(...args) {
71
- updatePath(state, args);
85
+ isArray && args.length === 1 ? updateArray(state, args[0]) : updatePath(state, args);
72
86
  }
73
87
  return [state, setStore];
74
88
  }
@@ -1,6 +1,6 @@
1
1
  const $RAW = Symbol("state-raw");
2
2
  function isWrappable(obj) {
3
- return obj != null && typeof obj === "object" && (obj.__proto__ === Object.prototype || Array.isArray(obj));
3
+ return obj != null && typeof obj === "object" && (Object.getPrototypeOf(obj) === Object.prototype || Array.isArray(obj));
4
4
  }
5
5
  function unwrap(item) {
6
6
  return item;
@@ -18,6 +18,19 @@ function mergeStoreNode(state, value, force) {
18
18
  setProperty(state, key, value[key], force);
19
19
  }
20
20
  }
21
+ function updateArray(current, next) {
22
+ if (typeof next === "function") next = next(current);
23
+ if (Array.isArray(next)) {
24
+ if (current === next) return;
25
+ let i = 0,
26
+ len = next.length;
27
+ for (; i < len; i++) {
28
+ const value = next[i];
29
+ if (current[i] !== value) setProperty(current, i, value);
30
+ }
31
+ setProperty(current, "length", len);
32
+ } else mergeStoreNode(current, next);
33
+ }
21
34
  function updatePath(current, path, traversed = []) {
22
35
  let part,
23
36
  next = current;
@@ -63,8 +76,9 @@ function updatePath(current, path, traversed = []) {
63
76
  } else setProperty(current, part, value);
64
77
  }
65
78
  function createStore(state) {
79
+ const isArray = Array.isArray(state);
66
80
  function setStore(...args) {
67
- updatePath(state, args);
81
+ isArray && args.length === 1 ? updateArray(state, args[0]) : updatePath(state, args);
68
82
  }
69
83
  return [state, setStore];
70
84
  }
@@ -28,7 +28,8 @@ function wrap$1(value, name) {
28
28
  return p;
29
29
  }
30
30
  function isWrappable(obj) {
31
- return obj != null && typeof obj === "object" && (obj[solidJs.$PROXY] || !obj.__proto__ || obj.__proto__ === Object.prototype || Array.isArray(obj));
31
+ let proto;
32
+ return obj != null && typeof obj === "object" && (obj[solidJs.$PROXY] || !(proto = Object.getPrototypeOf(obj)) || proto === Object.prototype || Array.isArray(obj));
32
33
  }
33
34
  function unwrap(item, set = new Set()) {
34
35
  let result, unwrapped, v, prop;
@@ -138,14 +139,16 @@ function mergeStoreNode(state, value) {
138
139
  function updateArray(current, next) {
139
140
  if (typeof next === "function") next = next(current);
140
141
  next = unwrap(next);
141
- if (current === next) return;
142
- let i = 0,
143
- len = next.length;
144
- for (; i < len; i++) {
145
- const value = next[i];
146
- if (current[i] !== value) setProperty(current, i, value);
147
- }
148
- setProperty(current, "length", len);
142
+ if (Array.isArray(next)) {
143
+ if (current === next) return;
144
+ let i = 0,
145
+ len = next.length;
146
+ for (; i < len; i++) {
147
+ const value = next[i];
148
+ if (current[i] !== value) setProperty(current, i, value);
149
+ }
150
+ setProperty(current, "length", len);
151
+ } else mergeStoreNode(current, next);
149
152
  }
150
153
  function updatePath(current, path, traversed = []) {
151
154
  let part,
@@ -269,11 +272,15 @@ function modifyMutable(state, modifier) {
269
272
  solidJs.batch(() => modifier(unwrap(state)));
270
273
  }
271
274
 
275
+ const $ROOT = Symbol("store-root");
272
276
  function applyState(target, parent, property, merge, key) {
273
277
  const previous = parent[property];
274
278
  if (target === previous) return;
275
279
  if (!isWrappable(target) || !isWrappable(previous) || key && target[key] !== previous[key]) {
276
- target !== previous && setProperty(parent, property, target);
280
+ if (target !== previous) {
281
+ if (property === $ROOT) return target;
282
+ setProperty(parent, property, target);
283
+ }
277
284
  return;
278
285
  }
279
286
  if (Array.isArray(target)) {
@@ -345,17 +352,19 @@ function reconcile(value, options = {}) {
345
352
  v = unwrap(value);
346
353
  return state => {
347
354
  if (!isWrappable(state) || !isWrappable(v)) return v;
348
- solidJs.batch(() => applyState(v, {
349
- state
350
- }, "state", merge, key));
351
- return state;
355
+ const res = applyState(v, {
356
+ [$ROOT]: state
357
+ }, $ROOT, merge, key);
358
+ return res === undefined ? state : res;
352
359
  };
353
360
  }
361
+ const producers = new WeakMap();
354
362
  const setterTraps = {
355
363
  get(target, property) {
356
364
  if (property === $RAW) return target;
357
365
  const value = target[property];
358
- return isWrappable(value) ? new Proxy(value, setterTraps) : value;
366
+ let proxy;
367
+ return isWrappable(value) ? producers.get(value) || (producers.set(value, proxy = new Proxy(value, setterTraps)), proxy) : value;
359
368
  },
360
369
  set(target, property, value) {
361
370
  setProperty(target, property, unwrap(value));
@@ -368,7 +377,13 @@ const setterTraps = {
368
377
  };
369
378
  function produce(fn) {
370
379
  return state => {
371
- if (isWrappable(state)) fn(new Proxy(state, setterTraps));
380
+ if (isWrappable(state)) {
381
+ let proxy;
382
+ if (!(proxy = producers.get(state))) {
383
+ producers.set(state, proxy = new Proxy(state, setterTraps));
384
+ }
385
+ fn(proxy);
386
+ }
372
387
  return state;
373
388
  };
374
389
  }
@@ -24,7 +24,8 @@ function wrap$1(value, name) {
24
24
  return p;
25
25
  }
26
26
  function isWrappable(obj) {
27
- return obj != null && typeof obj === "object" && (obj[$PROXY] || !obj.__proto__ || obj.__proto__ === Object.prototype || Array.isArray(obj));
27
+ let proto;
28
+ return obj != null && typeof obj === "object" && (obj[$PROXY] || !(proto = Object.getPrototypeOf(obj)) || proto === Object.prototype || Array.isArray(obj));
28
29
  }
29
30
  function unwrap(item, set = new Set()) {
30
31
  let result, unwrapped, v, prop;
@@ -134,14 +135,16 @@ function mergeStoreNode(state, value) {
134
135
  function updateArray(current, next) {
135
136
  if (typeof next === "function") next = next(current);
136
137
  next = unwrap(next);
137
- if (current === next) return;
138
- let i = 0,
139
- len = next.length;
140
- for (; i < len; i++) {
141
- const value = next[i];
142
- if (current[i] !== value) setProperty(current, i, value);
143
- }
144
- setProperty(current, "length", len);
138
+ if (Array.isArray(next)) {
139
+ if (current === next) return;
140
+ let i = 0,
141
+ len = next.length;
142
+ for (; i < len; i++) {
143
+ const value = next[i];
144
+ if (current[i] !== value) setProperty(current, i, value);
145
+ }
146
+ setProperty(current, "length", len);
147
+ } else mergeStoreNode(current, next);
145
148
  }
146
149
  function updatePath(current, path, traversed = []) {
147
150
  let part,
@@ -265,11 +268,15 @@ function modifyMutable(state, modifier) {
265
268
  batch(() => modifier(unwrap(state)));
266
269
  }
267
270
 
271
+ const $ROOT = Symbol("store-root");
268
272
  function applyState(target, parent, property, merge, key) {
269
273
  const previous = parent[property];
270
274
  if (target === previous) return;
271
275
  if (!isWrappable(target) || !isWrappable(previous) || key && target[key] !== previous[key]) {
272
- target !== previous && setProperty(parent, property, target);
276
+ if (target !== previous) {
277
+ if (property === $ROOT) return target;
278
+ setProperty(parent, property, target);
279
+ }
273
280
  return;
274
281
  }
275
282
  if (Array.isArray(target)) {
@@ -341,17 +348,19 @@ function reconcile(value, options = {}) {
341
348
  v = unwrap(value);
342
349
  return state => {
343
350
  if (!isWrappable(state) || !isWrappable(v)) return v;
344
- batch(() => applyState(v, {
345
- state
346
- }, "state", merge, key));
347
- return state;
351
+ const res = applyState(v, {
352
+ [$ROOT]: state
353
+ }, $ROOT, merge, key);
354
+ return res === undefined ? state : res;
348
355
  };
349
356
  }
357
+ const producers = new WeakMap();
350
358
  const setterTraps = {
351
359
  get(target, property) {
352
360
  if (property === $RAW) return target;
353
361
  const value = target[property];
354
- return isWrappable(value) ? new Proxy(value, setterTraps) : value;
362
+ let proxy;
363
+ return isWrappable(value) ? producers.get(value) || (producers.set(value, proxy = new Proxy(value, setterTraps)), proxy) : value;
355
364
  },
356
365
  set(target, property, value) {
357
366
  setProperty(target, property, unwrap(value));
@@ -364,7 +373,13 @@ const setterTraps = {
364
373
  };
365
374
  function produce(fn) {
366
375
  return state => {
367
- if (isWrappable(state)) fn(new Proxy(state, setterTraps));
376
+ if (isWrappable(state)) {
377
+ let proxy;
378
+ if (!(proxy = producers.get(state))) {
379
+ producers.set(state, proxy = new Proxy(state, setterTraps));
380
+ }
381
+ fn(proxy);
382
+ }
368
383
  return state;
369
384
  };
370
385
  }
@@ -1,7 +1,6 @@
1
- import { DeepMutable } from "./store";
2
1
  export declare type ReconcileOptions = {
3
2
  key?: string | null;
4
3
  merge?: boolean;
5
4
  };
6
5
  export declare function reconcile<T extends U, U>(value: T, options?: ReconcileOptions): (state: U) => T;
7
- export declare function produce<T>(fn: (state: DeepMutable<T>) => void): (state: T) => T;
6
+ export declare function produce<T>(fn: (state: T) => void): (state: T) => T;
@@ -1,7 +1,7 @@
1
- import type { DeepMutable, SetStoreFunction, Store } from "store";
1
+ import type { SetStoreFunction, Store } from "store";
2
2
  export declare const $RAW: unique symbol;
3
3
  export declare function isWrappable(obj: any): boolean;
4
- export declare function unwrap<T>(item: any): T;
4
+ export declare function unwrap<T>(item: T): T;
5
5
  export declare function setProperty(state: any, property: PropertyKey, value: any, force?: boolean): void;
6
6
  export declare function updatePath(current: any, path: any[], traversed?: PropertyKey[]): void;
7
7
  export declare function createStore<T>(state: T | Store<T>): [Store<T>, SetStoreFunction<T>];
@@ -11,5 +11,5 @@ declare type ReconcileOptions = {
11
11
  merge?: boolean;
12
12
  };
13
13
  export declare function reconcile<T extends U, U>(value: T, options?: ReconcileOptions): (state: U) => T;
14
- export declare function produce<T>(fn: (state: DeepMutable<T>) => void): (state: T) => T;
14
+ export declare function produce<T>(fn: (state: T) => void): (state: T) => T;
15
15
  export {};