solid-ctrl-flow 6.0.0 → 6.1.1

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/dist/index.d.ts CHANGED
@@ -11,6 +11,14 @@ export declare function Case(props: ParentProps<{
11
11
  value: unknown;
12
12
  }>): JSX;
13
13
 
14
+ /**
15
+ * Runs {@link f} and ensures that its reactive resources are cleaned up not only when the current {@link Owner} is disposed, but also when the provided one is
16
+ * @param outer The {@link Owner} for which to listen for its disposal
17
+ * @param f The function to run
18
+ * @return The same thing {@link f} returned
19
+ */
20
+ export declare function disposeWithOwner<T>(outer: Owner, f: Accessor<T>): T;
21
+
14
22
  /**
15
23
  * Eventually wraps its content into a template if a certain condition is met.
16
24
  * If you set {@link Standard.recycled} to `true`, the content will be memoized in the beginning and will be recycled even if the wrapper changes.
@@ -55,17 +63,23 @@ export declare class Extractor {
55
63
  constructor(name?: string);
56
64
  readonly ctx: Context<State | undefined>;
57
65
  Joint: (props: {
58
- children?: JSX.Element;
59
- }) => JSX.Element;
66
+ children?: JSX;
67
+ }) => JSX;
60
68
  Dest: (props: {
61
- children?: JSX.Element;
62
- }) => JSX.Element;
63
- Source: (props: Info) => JSX.Element;
69
+ children?: JSX;
70
+ }) => JSX;
71
+ Source: (props: Info) => JSX;
64
72
  SameContextSource: (props: {
65
73
  order?: number | undefined;
66
74
  } & {
67
- children?: JSX.Element;
68
- }) => JSX.Element;
75
+ children?: JSX;
76
+ }) => JSX;
77
+ /**
78
+ * Returns the number of sources available for the current {@link Extractor}.
79
+ * It's a getter that returns a function that will be bound to the {@link Owner} in which the getter was called.
80
+ * If the current {@link Owner} is NOT under a {@link Joint}, it will return `undefined`
81
+ */
82
+ get getSourceCount(): (() => number) | undefined;
69
83
  /**
70
84
  * Returns the number of destinations available for the current {@link Extractor}.
71
85
  * It's a getter that returns a function that will be bound to the {@link Owner} in which the getter was called.
@@ -193,9 +207,12 @@ declare type Standard<T> = ParentProps<{
193
207
  declare class State {
194
208
  #private;
195
209
  get sources(): OrderedLinkedList<Info>;
210
+ get sourceCount(): number;
196
211
  get destCount(): number;
197
- shift(k: number): void;
198
212
  force(): void;
213
+ shiftSource(k: number): void;
214
+ shiftDest(k: number): void;
215
+ shiftSourceAndForce(k: number): void;
199
216
  }
200
217
 
201
218
  /** Type of an element wrapping call-back which accepts an additional parameter */
package/dist/index.mjs CHANGED
@@ -1,8 +1,16 @@
1
- import { untrack, createRoot, getOwner, createMemo, Show, createContext, useContext, onCleanup, For, createRenderEffect, on, splitProps, createSignal, createSelector, equalFn, Match, runWithOwner } from "solid-js";
1
+ import { untrack, getOwner, createRoot, runWithOwner, onCleanup, createMemo, Show, createContext, useContext, For, createRenderEffect, on, splitProps, createSignal, batch, createSelector, equalFn, Match } from "solid-js";
2
2
  import { createComponent, memo, mergeProps, spread } from "solid-js/web";
3
3
  function untrackCall(f, ...args) {
4
4
  return untrack(() => f.apply(this, args));
5
5
  }
6
+ function disposeWithOwner(outer, f) {
7
+ const inner = getOwner();
8
+ return createRoot((d) => {
9
+ runWithOwner(outer, () => onCleanup(d));
10
+ runWithOwner(inner, () => onCleanup(d));
11
+ return f();
12
+ });
13
+ }
6
14
  function runWithContext(ctx2, value, f) {
7
15
  return createRoot((d) => {
8
16
  try {
@@ -85,24 +93,37 @@ const COMPARATOR = (a, b) => (a.order ?? 0) - (b.order ?? 0);
85
93
  const SOURCES_OPTS = {
86
94
  internal: true,
87
95
  equals: false
88
- }, DEST_COUNT_OPTS = {
96
+ }, COUNT_OPTS = {
89
97
  internal: true
90
98
  };
91
99
  class State {
92
100
  #sources = createSignal(new OrderedLinkedList(), SOURCES_OPTS);
93
- #destCount = createSignal(0, DEST_COUNT_OPTS);
101
+ #sourceCount = createSignal(0, COUNT_OPTS);
102
+ #destCount = createSignal(0, COUNT_OPTS);
94
103
  get sources() {
95
104
  return this.#sources[0]();
96
105
  }
106
+ get sourceCount() {
107
+ return this.#sourceCount[0]();
108
+ }
97
109
  get destCount() {
98
110
  return this.#destCount[0]();
99
111
  }
100
- shift(k) {
101
- this.#destCount[1]((v) => v + k);
102
- }
103
112
  force() {
104
113
  this.#sources[1]((v) => v);
105
114
  }
115
+ shiftSource(k) {
116
+ this.#sourceCount[1]((v) => v + k);
117
+ }
118
+ shiftDest(k) {
119
+ this.#destCount[1]((v) => v + k);
120
+ }
121
+ shiftSourceAndForce(k) {
122
+ batch(() => {
123
+ this.shiftSource(k);
124
+ this.force();
125
+ });
126
+ }
106
127
  }
107
128
  class Extractor {
108
129
  constructor(name) {
@@ -115,6 +136,15 @@ class Extractor {
115
136
  Dest = Dest.bind(this);
116
137
  Source = Source.bind(this);
117
138
  SameContextSource = SameContextSource.bind(this);
139
+ /**
140
+ * Returns the number of sources available for the current {@link Extractor}.
141
+ * It's a getter that returns a function that will be bound to the {@link Owner} in which the getter was called.
142
+ * If the current {@link Owner} is NOT under a {@link Joint}, it will return `undefined`
143
+ */
144
+ get getSourceCount() {
145
+ const state = useContext(this.ctx);
146
+ return state && (() => state.sourceCount);
147
+ }
118
148
  /**
119
149
  * Returns the number of destinations available for the current {@link Extractor}.
120
150
  * It's a getter that returns a function that will be bound to the {@link Owner} in which the getter was called.
@@ -138,8 +168,8 @@ function Dest(props) {
138
168
  const state = useContext(this.ctx);
139
169
  if (!state)
140
170
  return memo(() => props.children);
141
- onCleanup(() => state.shift(-1));
142
- state.shift(1);
171
+ onCleanup(() => state.shiftDest(-1));
172
+ state.shiftDest(1);
143
173
  return createComponent(For, {
144
174
  get each() {
145
175
  return [...state.sources];
@@ -158,22 +188,23 @@ function Source(props) {
158
188
  sources
159
189
  } = state;
160
190
  const order = createMemo(() => props.order);
191
+ const owner = getOwner();
161
192
  const info = {
162
193
  get order() {
163
194
  return order();
164
195
  },
165
196
  get children() {
166
- return props.children;
197
+ return disposeWithOwner(owner, () => props.children);
167
198
  }
168
199
  };
169
200
  const node = new OrderedLinkedListNode(info);
170
201
  createRenderEffect(on(order, () => {
171
202
  onCleanup(() => {
172
203
  node.remove();
173
- state.force();
204
+ state.shiftSourceAndForce(-1);
174
205
  });
175
206
  sources.add(node, COMPARATOR);
176
- state.force();
207
+ state.shiftSourceAndForce(1);
177
208
  }));
178
209
  }
179
210
  function SameContextSource(props) {
@@ -269,6 +300,7 @@ export {
269
300
  OrderedLinkedListNode,
270
301
  SameContext,
271
302
  Spread,
303
+ disposeWithOwner,
272
304
  memoProps,
273
305
  runWithContext,
274
306
  splitAndMemoProps,
package/dist/index.umd.js CHANGED
@@ -5,6 +5,14 @@
5
5
  function untrackCall(f, ...args) {
6
6
  return solidJs.untrack(() => f.apply(this, args));
7
7
  }
8
+ function disposeWithOwner(outer, f) {
9
+ const inner = solidJs.getOwner();
10
+ return solidJs.createRoot((d) => {
11
+ solidJs.runWithOwner(outer, () => solidJs.onCleanup(d));
12
+ solidJs.runWithOwner(inner, () => solidJs.onCleanup(d));
13
+ return f();
14
+ });
15
+ }
8
16
  function runWithContext(ctx2, value, f) {
9
17
  return solidJs.createRoot((d) => {
10
18
  try {
@@ -87,24 +95,37 @@
87
95
  const SOURCES_OPTS = {
88
96
  internal: true,
89
97
  equals: false
90
- }, DEST_COUNT_OPTS = {
98
+ }, COUNT_OPTS = {
91
99
  internal: true
92
100
  };
93
101
  class State {
94
102
  #sources = solidJs.createSignal(new OrderedLinkedList(), SOURCES_OPTS);
95
- #destCount = solidJs.createSignal(0, DEST_COUNT_OPTS);
103
+ #sourceCount = solidJs.createSignal(0, COUNT_OPTS);
104
+ #destCount = solidJs.createSignal(0, COUNT_OPTS);
96
105
  get sources() {
97
106
  return this.#sources[0]();
98
107
  }
108
+ get sourceCount() {
109
+ return this.#sourceCount[0]();
110
+ }
99
111
  get destCount() {
100
112
  return this.#destCount[0]();
101
113
  }
102
- shift(k) {
103
- this.#destCount[1]((v) => v + k);
104
- }
105
114
  force() {
106
115
  this.#sources[1]((v) => v);
107
116
  }
117
+ shiftSource(k) {
118
+ this.#sourceCount[1]((v) => v + k);
119
+ }
120
+ shiftDest(k) {
121
+ this.#destCount[1]((v) => v + k);
122
+ }
123
+ shiftSourceAndForce(k) {
124
+ solidJs.batch(() => {
125
+ this.shiftSource(k);
126
+ this.force();
127
+ });
128
+ }
108
129
  }
109
130
  class Extractor {
110
131
  constructor(name) {
@@ -117,6 +138,15 @@
117
138
  Dest = Dest.bind(this);
118
139
  Source = Source.bind(this);
119
140
  SameContextSource = SameContextSource.bind(this);
141
+ /**
142
+ * Returns the number of sources available for the current {@link Extractor}.
143
+ * It's a getter that returns a function that will be bound to the {@link Owner} in which the getter was called.
144
+ * If the current {@link Owner} is NOT under a {@link Joint}, it will return `undefined`
145
+ */
146
+ get getSourceCount() {
147
+ const state = solidJs.useContext(this.ctx);
148
+ return state && (() => state.sourceCount);
149
+ }
120
150
  /**
121
151
  * Returns the number of destinations available for the current {@link Extractor}.
122
152
  * It's a getter that returns a function that will be bound to the {@link Owner} in which the getter was called.
@@ -140,8 +170,8 @@
140
170
  const state = solidJs.useContext(this.ctx);
141
171
  if (!state)
142
172
  return web.memo(() => props.children);
143
- solidJs.onCleanup(() => state.shift(-1));
144
- state.shift(1);
173
+ solidJs.onCleanup(() => state.shiftDest(-1));
174
+ state.shiftDest(1);
145
175
  return web.createComponent(solidJs.For, {
146
176
  get each() {
147
177
  return [...state.sources];
@@ -160,22 +190,23 @@
160
190
  sources
161
191
  } = state;
162
192
  const order = solidJs.createMemo(() => props.order);
193
+ const owner = solidJs.getOwner();
163
194
  const info = {
164
195
  get order() {
165
196
  return order();
166
197
  },
167
198
  get children() {
168
- return props.children;
199
+ return disposeWithOwner(owner, () => props.children);
169
200
  }
170
201
  };
171
202
  const node = new OrderedLinkedListNode(info);
172
203
  solidJs.createRenderEffect(solidJs.on(order, () => {
173
204
  solidJs.onCleanup(() => {
174
205
  node.remove();
175
- state.force();
206
+ state.shiftSourceAndForce(-1);
176
207
  });
177
208
  sources.add(node, COMPARATOR);
178
- state.force();
209
+ state.shiftSourceAndForce(1);
179
210
  }));
180
211
  }
181
212
  function SameContextSource(props) {
@@ -270,6 +301,7 @@
270
301
  exports2.OrderedLinkedListNode = OrderedLinkedListNode;
271
302
  exports2.SameContext = SameContext;
272
303
  exports2.Spread = Spread;
304
+ exports2.disposeWithOwner = disposeWithOwner;
273
305
  exports2.memoProps = memoProps;
274
306
  exports2.runWithContext = runWithContext;
275
307
  exports2.splitAndMemoProps = splitAndMemoProps;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "solid-ctrl-flow",
3
- "version": "6.0.0",
3
+ "version": "6.1.1",
4
4
  "description": "Control flow components for solid-js",
5
5
  "author": "AFatNiBBa",
6
6
  "license": "ISC",
package/readMe.md CHANGED
@@ -196,6 +196,8 @@ return <>
196
196
  </e.Joint>
197
197
  </>
198
198
  ```
199
+ > Same applies to `Extractor.getSourceCount()`
200
+
199
201
  You can use `Extractor.SameContextSource` to automate the process of using a `SameContext` inside a `Extractor.Source`. When in doubt, use `Extractor.SameContextSource` instead of `Extractor.Source`
200
202
  ```tsx
201
203
  const e = new Extractor(), ctx = createContext(1);
@@ -233,5 +235,8 @@ Like `splitProps()` but passes the every part except the last one to [`memoProps
233
235
  ### `untrackCall()`
234
236
  Calls a function untracking what happens inside of it but not what gets passed as its argument
235
237
 
238
+ ### `disposeWithOwner()`
239
+ Calls a function in a way that makes it so that the reactive resources it creates are managed by 2 `Owner`s
240
+
236
241
  ### `runWithContext()`
237
242
  Creates a context scope that persists for the duration of a function