@poveste/plugin-vue 0.2.1 → 0.3.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.
@@ -90,17 +90,33 @@ function _toRawObject(obj: Record<any, any>, target: Record<any, any>, seen = ne
90
90
  * @param externalState Reactive state created with the external/user Vue
91
91
  */
92
92
  export function syncStateBundledAndExternal(bundledState, externalState) {
93
+ // `syncing` means "the next firing on the other side is the echo of a write I
94
+ // just made, ignore it". The subtlety, and the whole of #95, is that it is
95
+ // only safe to set when a firing is actually coming.
96
+ //
97
+ // It used to be set unconditionally, on the assumption that every apply
98
+ // provokes exactly one counterpart firing. Nothing enforced that. A change
99
+ // `applyState` cannot express — a removed key is the simplest — provokes none,
100
+ // and the flag then sat set through the next genuine edit and swallowed it.
101
+ //
102
+ // What held the assumption up in practice was an accident: `applyState`
103
+ // rebuilt every object it copied, so any state carrying an object or an array
104
+ // triggered the far side whether or not a value had moved. Vue stories always
105
+ // carry `_hPropState` and `_hPropDefs`, so in this plugin it never actually
106
+ // bit — which is exactly why the issue had no repro, and why making
107
+ // `applyState` skip no-op writes had to come with this change rather than
108
+ // before it.
109
+ //
110
+ // `applyState` now reports whether it wrote, and that is what the flag holds.
93
111
  let syncing = false
94
112
 
95
113
  const _stop = _watch(() => bundledState, (value) => {
96
114
  if (value == null) return
97
- if (!syncing) {
98
- syncing = true
99
- applyState(externalState, _toRawDeep(value))
100
- }
101
- else {
115
+ if (syncing) {
102
116
  syncing = false
117
+ return
103
118
  }
119
+ syncing = applyState(externalState, _toRawDeep(value))
104
120
  }, {
105
121
  deep: true,
106
122
  immediate: true,
@@ -108,13 +124,11 @@ export function syncStateBundledAndExternal(bundledState, externalState) {
108
124
 
109
125
  const stop = watch(() => externalState, (value) => {
110
126
  if (value == null) return
111
- if (!syncing) {
112
- syncing = true
113
- applyState(bundledState, toRawDeep(value))
114
- }
115
- else {
127
+ if (syncing) {
116
128
  syncing = false
129
+ return
117
130
  }
131
+ syncing = applyState(bundledState, toRawDeep(value))
118
132
  }, {
119
133
  deep: true,
120
134
  immediate: true,
@@ -56,7 +56,7 @@ async function printVNode(vnode: VNode, propsOverrides: Record<string, any> = nu
56
56
  }
57
57
  if (valueCode) {
58
58
  // Cleanup render code
59
- valueCode = valueCode.replace(/^\$(setup|props|data)\./g, '')
59
+ valueCode = valueCode.replace(/^\$(?:setup|props|data)\./g, '')
60
60
  }
61
61
  const valueLines = valueCode ? [valueCode] : serializeAndCleanJs(dir.value)
62
62
  const attr: string[] = []
@@ -1,5 +1,6 @@
1
1
  import type { ServerStory, ServerVariant } from '@poveste/shared'
2
- import { defineComponent, inject, type PropType } from 'vue'
2
+ import type { PropType } from 'vue'
3
+ import { defineComponent, inject } from 'vue'
3
4
 
4
5
  export default defineComponent({
5
6
  name: 'PovesteVariant',
package/tsconfig.json CHANGED
@@ -9,7 +9,7 @@
9
9
  ],
10
10
  "rootDir": "src",
11
11
  "module": "ESNext",
12
- "moduleResolution": "node",
12
+ "moduleResolution": "bundler",
13
13
  "resolveJsonModule": true,
14
14
  "types": [
15
15
  "node"
@@ -0,0 +1,13 @@
1
+ import { fileURLToPath } from 'node:url'
2
+ import { defineConfig } from 'vitest/config'
3
+
4
+ export default defineConfig({
5
+ resolve: {
6
+ alias: {
7
+ // Point at the source, not `dist`. The state-sync tests exist to catch a
8
+ // regression in `applyState`, and resolving the published entry would test
9
+ // whatever was last built instead of what is in the tree.
10
+ '@poveste/shared': fileURLToPath(new URL('../poveste-shared/src/index.ts', import.meta.url)),
11
+ },
12
+ },
13
+ })