Skip to content

Commit ffcb1e8

Browse files
committed
Add more info to solid-usage.md
1 parent b908bbd commit ffcb1e8

1 file changed

Lines changed: 70 additions & 64 deletions

File tree

solid-usage.md

Lines changed: 70 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,48 @@
1-
# Current usage
1+
# Usage of Solid internals and dev-apis in solid-devtools
22

3-
## Node types
3+
## Current usage
44

5-
By node I mean any solid internal object, like owners, signals, roots, store-nodes, and anything user registers with `solid.DEV.registerGraph()`.
5+
### Detecting Solid
66

7-
There are many internal owner properties that are inspected to determine kind of node. — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/main/utils.ts#L5-L86)
7+
- This one cannot use internals nor dev-only apis because the goal is to detect solid on any page. — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/shared/src/detect.ts)
88

9-
### Issues
9+
#### Issues
1010

11-
This is super brittle, some properties are set some time after the owner is created, most of the properties accessed are not used for anything else.
11+
- The test is complicated, brittle, might have false-positives and doesn't tell you the solid version.
1212

13-
## Node names
13+
### Node types
1414

15-
- `owner.name` or `signal.name` or `owner.component.name` or `owner.component.displayName`
15+
By node I mean any solid internal object, like owners, signals, roots, store-nodes, and anything user registers with `solid.DEV.registerGraph()`.
1616

17-
### Issues
17+
- There are many internal owner properties that are inspected to determine kind of node. — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/main/utils.ts#L5-L86)
1818

19-
No one good way to give custom names to components.
19+
#### Issues
2020

21-
This works but it's a side-effect.
21+
- This is super brittle, some properties are set some time after the owner is created, most of the properties accessed are not used for anything else.
22+
23+
### Node names
24+
25+
- `owner.name` or `signal.name` or `owner.component.name` or `owner.component.displayName`
2226

23-
```js
24-
Bar.displayName = "Foo.Bar"
25-
```
27+
#### Issues
2628

27-
While this is ugly
29+
- No one good way to give custom names to components.
2830

29-
```ts
30-
if (isDev) {
31-
getOwner()!.name = "Foo.Bar"
32-
}
33-
```
31+
This works but it's a side-effect.
3432

35-
## Roots
33+
```js
34+
Bar.displayName = "Foo.Bar"
35+
```
36+
37+
While this is ugly
38+
39+
```ts
40+
if (isDev) {
41+
getOwner()!.name = "Foo.Bar"
42+
}
43+
```
44+
45+
### Roots
3646

3747
- `solid.DEV.hooks.afterCreateOwner()` for attaching the debugger to roots
3848
- to gather top-level roots like `render()`
@@ -42,41 +52,45 @@ if (isDev) {
4252
- so that if the root's parent disposes before the root, the root will need to be "reattached" to first found "alive" owner
4353
- this is rather uncommon
4454

45-
### Issues
55+
#### Issues
4656

47-
Any root created before `solid.DEV.hooks.afterCreateOwner` is set will be missed.\
48-
This is annoying because the extension's content-script isn't garanteed to run before user scripts. Making the `solid-devtools` npm package and `import "solid-devtools"` required to capture all the roots.\
49-
If there was access to any unowned root, the extension would work with any solid app with no setup.
57+
- Any root created before `solid.DEV.hooks.afterCreateOwner` is set will be missed.\
58+
This is annoying because the extension's content-script isn't garanteed to run before user scripts. Making the `solid-devtools` npm package and `import "solid-devtools"` required to capture all the roots.\
59+
If there was access to any unowned root, the extension would work with any solid app with no setup.
5060

51-
## Computation updates
61+
### Owners tree
5262

53-
- `owner.fn` is patched to observe when the computration reruns — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/main/observe.ts#L50-L88)
63+
- Reads `owner.owner` and `owner.owned` to walk the tree in both directions
5464

55-
- `owner.value` is read to get the current owner value and patched to listen to changes — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/main/observe.ts#L98-L123)
56-
- signals are being observed the same way
57-
- this is also separate from observing `owner.fn` because not every rerun will cause the value to update *(thanks to `equals` option)*
65+
### Owner disposing
5866

59-
- `owner.sources` — by listening to each of the sources, I'm able to tell which source caused the computation to rerun. — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/logger/src/index.ts#L117-L180)
67+
- Patching `owner.cleanups` to listen to cleanup of any owner — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/main/utils.ts#L205-L227)
68+
69+
#### Issues
6070

61-
## Owners tree
71+
- The cleanups are executed depth first—if I try to walk the tree on child's cleanup, I cannot tell if the parent is getting cleaned up as well or not. There is no `isDisposed` property.
6272

63-
Reads `owner.owner` and `owner.owned` to walk the tree in both directions
73+
- There is no difference between disposing and rerunning—I have to listen to parents cleanup to when targetting disposal.
6474

65-
## Owner disposing
75+
### Computation updates
6676

67-
Patching `owner.cleanups` to listen to cleanup of any owner [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/main/utils.ts#L205-L227)
77+
- `owner.fn` is patched to observe when the computration reruns [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/main/observe.ts#L50-L88)
6878

69-
### Issues
79+
- `owner.value` is read to get the current owner value and patched to listen to changes — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/main/observe.ts#L98-L123)
80+
- signals are being observed the same way
81+
- this is also separate from observing `owner.fn` because not every rerun will cause the value to update *(thanks to `equals` option)*
7082

71-
The cleanups are executed depth first—if I try to walk the tree on child's cleanup, I cannot tell if the parent is getting cleaned up as well or not. There is no `isDisposed` property.
83+
- `owner.sources` — by listening to each of the sources, I'm able to tell which source caused the computation to rerun. — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/logger/src/index.ts#L117-L180)
7284

73-
## Dependency graph
85+
### Dependency graph
7486

75-
- `owner.sources` and `owner.observers`
87+
- `owner.sources` and `owner.observers` to crawl the graph
7688

7789
- `sourceValue.graph` — for signals to know to which owner they "belong to"
7890

79-
## Props
91+
- `solid.DEV.hooks.afterUpdate()` is used as a trigger to update the dependency graph
92+
93+
### Props
8094

8195
- `solid.$PROXY` is used to check if the props object is a proxy
8296

@@ -86,7 +100,7 @@ The cleanups are executed depth first—if I try to walk the tree on child's cle
86100

87101
- For proxy props I can only get keys with `Object.keys(props)`
88102

89-
### Issues
103+
#### Issues
90104

91105
- I cannot intercept proxy props—users just see `foo: unknown` without the value
92106

@@ -98,42 +112,34 @@ The cleanups are executed depth first—if I try to walk the tree on child's cle
98112
- I would have to do `Object.defineProperty(owner, "props", {set})` to be able to patch props before component function executes probably
99113
- [source code](https://github.com/solidjs/solid/blob/main/packages/solid/src/reactive/signal.ts#L1115-L1133)
100114

101-
## Store
115+
### Store
102116

103117
- `store.unwrap()` with type reflection when serializing and reading stores
104118

105119
- `store.isWrappable()`
106120

107121
- `store.DEV.hooks.onStoreNodeUpdate()` for observing changes to stores — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/inspector/store.ts#L27-L49)
108122

109-
### Issues
123+
#### Issues
110124

111-
There is no connection between signals and the store-nodes they are being used in.\
125+
- There is no connection between signals and the store-nodes they are being used in.\
112126
So if there is an effect that listens to some store property *(e.g. `createEffect(() => store.foo)`)*, from devtools perspective this is just some random signal being observed in `owner.sources`.
113127

114-
## Source Map
128+
### Signals and other values
129+
130+
- `owner.sourceMap` for getting which signals, stores or custom values belong to an owner.
131+
132+
- `solid.DEV.hooks.afterCreateSignal()` is useful for getting unowned signals
133+
- which is important for the `export const [state, setState] = solid.createSignal({...})` style of state management — [source code](https://github.com/thetarnav/solid-devtools/blob/main/packages/debugger/src/setup.ts#L123-L136)
115134

116-
- `owner.sourceMap`
135+
#### Issues
117136

118-
## Source Map
137+
- The two issues with `afterCreateSignal` are addressed by https://github.com/solidjs/solid/pull/2396 and https://github.com/solidjs/solid/pull/2393
119138

120-
- `solid.DEV.hooks.afterCreateSignal()`
121-
- `solid.DEV.registerGraph()`
122-
- `owner.sourceMap`
139+
- The other is similar to `afterCreateOwner` — signals created before the hook callback is set will be missed. This one is trickier to solve because signals don't have a clear lifecycle unlike roots.
123140

124-
## List
141+
## Additional issues
125142

126-
- `solid.$PROXY` in [props](#props)
127-
- `Object.defineProperty(props, key, {get})` in [props](#props)
128-
- `solid.getListener() + solid.onCleanup()` in [props](#props)
129-
- `store.unwrap()` in [store](#store)
130-
- `store.isWrappable()` in [store](#store)
131-
- `store.DEV.hooks.onStoreNodeUpdate()` in [store](#store)
132-
- `solid.DEV.hooks.afterCreateOwner()` in [owners](#owners)
133-
- `owner.owner` in [owners](#owners)
134-
- `owner.cleanups` in [owners](#owners)
143+
- There is no way to connect a render effect to the dom property it updates, so I cannot give any meaningfull info about them, or to which element they even belong.
135144

136-
# Future
137-
- `onOwnerCleanup` - to not patch `owner.cleanups`
138-
- it probably would be useful to have both `onBeforeOwnerCleanup` and `onAfterOwnerCleanup`
139-
as the cleanups are executed depth first—if I try to walk the tree on child's cleanup, I cannot tell if the parent is getting cleaned up as well or not.
145+
- There is no connection between a signal accessor and the signal object it belongs to.

0 commit comments

Comments
 (0)