@codonsplice/wasm 0.2.3 → 0.2.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/astro/index.js CHANGED
@@ -4,3 +4,8 @@
4
4
  // helpers; use them inside a client:* island (or any of the framework wrappers
5
5
  // for reactive state).
6
6
  export { execute, stream, compile, check, ast, initEngine, CodonSplice } from '@codonsplice/wasm/helpers'
7
+
8
+ // Re-export the SpliceQL editor primitives. Astro islands mount the editor with
9
+ // `mountSpliceEditor(el, { doc, onChange })` inside a <script> / client:* island,
10
+ // or compose `spliceqlExtensions()` into a custom CodeMirror view.
11
+ export { mountSpliceEditor, spliceqlExtensions } from '@codonsplice/editor'
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@codonsplice/astro",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
- "dependencies": { "@codonsplice/wasm": "^0.2.3" },
6
+ "dependencies": { "@codonsplice/wasm": "^0.2.4", "@codonsplice/editor": "^0.2.4" },
7
7
  "license": "MIT"
8
8
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codonsplice/wasm",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "description": "CodonSplice — run SpliceQL genomic queries (BAM/VCF) in the browser via WASM",
5
5
  "type": "module",
6
6
  "main": "codonsplice_wasm.js",
package/react/index.js CHANGED
@@ -1,10 +1,54 @@
1
- // @codonsplice/react — a useSpliceQL() hook over @codonsplice/wasm.
2
- import { useState, useCallback } from 'react'
1
+ // @codonsplice/react — a useSpliceQL() hook + <SpliceEditor> over @codonsplice/wasm.
2
+ import { useState, useCallback, useRef, useEffect, createElement } from 'react'
3
3
  import { execute as csExecute } from '@codonsplice/wasm/helpers'
4
+ import { mountSpliceEditor } from '@codonsplice/editor'
4
5
 
5
6
  // Re-export the core tooling so apps can `import { useSpliceQL, compile, check }
6
7
  // from '@codonsplice/react'` without depending on @codonsplice/wasm directly.
7
8
  export { execute, stream, compile, check, ast, initEngine } from '@codonsplice/wasm/helpers'
9
+ // Re-export the editor primitives for apps that want to mount their own view.
10
+ export { spliceqlExtensions, mountSpliceEditor } from '@codonsplice/editor'
11
+
12
+ // A controlled CodeMirror 6 SpliceQL editor.
13
+ //
14
+ // import { SpliceEditor } from '@codonsplice/react'
15
+ // <SpliceEditor value={query} onChange={setQuery} className="editor" style={{ height: 240 }} />
16
+ //
17
+ // Props:
18
+ // value — the editor's document (controlled; external changes are reconciled)
19
+ // onChange — (docString) => void, fired on every edit
20
+ // className — passed to the host <div>
21
+ // style — passed to the host <div>
22
+ export function SpliceEditor({ value = '', onChange, className, style }) {
23
+ const host = useRef(null)
24
+ const viewRef = useRef(null)
25
+ const onChangeRef = useRef(onChange)
26
+ onChangeRef.current = onChange
27
+
28
+ useEffect(() => {
29
+ const view = mountSpliceEditor(host.current, {
30
+ doc: value,
31
+ onChange: (v) => { onChangeRef.current && onChangeRef.current(v) },
32
+ })
33
+ viewRef.current = view
34
+ return () => { view.destroy(); viewRef.current = null }
35
+ // Mount once; external value changes are reconciled by the effect below.
36
+ // eslint-disable-next-line react-hooks/exhaustive-deps
37
+ }, [])
38
+
39
+ // Reconcile a controlled `value` that diverges from the editor's contents
40
+ // (e.g. set programmatically), without clobbering in-progress typing.
41
+ useEffect(() => {
42
+ const view = viewRef.current
43
+ if (!view) return
44
+ const current = view.state.doc.toString()
45
+ if (value !== current) {
46
+ view.dispatch({ changes: { from: 0, to: current.length, insert: value ?? '' } })
47
+ }
48
+ }, [value])
49
+
50
+ return createElement('div', { ref: host, className, style })
51
+ }
8
52
 
9
53
  export function useSpliceQL() {
10
54
  const [result, setResult] = useState(null)
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@codonsplice/react",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
- "dependencies": { "@codonsplice/wasm": "^0.2.3" },
6
+ "dependencies": { "@codonsplice/wasm": "^0.2.4", "@codonsplice/editor": "^0.2.4" },
7
7
  "peerDependencies": { "react": "*" },
8
8
  "license": "MIT"
9
9
  }
package/svelte/index.js CHANGED
@@ -1,10 +1,42 @@
1
- // @codonsplice/svelte — a createSpliceQL() store factory over @codonsplice/wasm.
1
+ // @codonsplice/svelte — a createSpliceQL() store factory + spliceEditor action
2
+ // over @codonsplice/wasm.
2
3
  import { writable } from 'svelte/store'
3
4
  import { execute as csExecute } from '@codonsplice/wasm/helpers'
5
+ import { mountSpliceEditor } from '@codonsplice/editor'
4
6
 
5
7
  // Re-export the core tooling so apps can `import { createSpliceQL, compile,
6
8
  // check } from '@codonsplice/svelte'` without depending on @codonsplice/wasm.
7
9
  export { execute, stream, compile, check, ast, initEngine } from '@codonsplice/wasm/helpers'
10
+ // Re-export the editor primitives for apps that want to mount their own view.
11
+ export { spliceqlExtensions, mountSpliceEditor } from '@codonsplice/editor'
12
+
13
+ // A Svelte action that mounts a CodeMirror 6 SpliceQL editor into the node:
14
+ //
15
+ // <script>
16
+ // let query = 'FROM bam "x.bam" CALL variants'
17
+ // </script>
18
+ // <div use:spliceEditor={{ value: query, onChange: (v) => (query = v) }} />
19
+ //
20
+ // Params:
21
+ // value — the editor's initial/controlled document (external changes reconciled)
22
+ // onChange — (docString) => void, fired on every edit
23
+ export function spliceEditor(node, { value = '', onChange } = {}) {
24
+ const view = mountSpliceEditor(node, {
25
+ doc: value,
26
+ onChange: (v) => { onChange && onChange(v) },
27
+ })
28
+ return {
29
+ // Reconcile an external `value` change without clobbering live typing.
30
+ update({ value: next = '', onChange: nextOnChange } = {}) {
31
+ onChange = nextOnChange
32
+ const current = view.state.doc.toString()
33
+ if (next !== current) {
34
+ view.dispatch({ changes: { from: 0, to: current.length, insert: next ?? '' } })
35
+ }
36
+ },
37
+ destroy() { view.destroy() },
38
+ }
39
+ }
8
40
 
9
41
  export function createSpliceQL() {
10
42
  const result = writable(null)
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@codonsplice/svelte",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
- "dependencies": { "@codonsplice/wasm": "^0.2.3" },
6
+ "dependencies": { "@codonsplice/wasm": "^0.2.4", "@codonsplice/editor": "^0.2.4" },
7
7
  "peerDependencies": { "svelte": "*" },
8
8
  "license": "MIT"
9
9
  }
package/vue/index.js CHANGED
@@ -1,10 +1,53 @@
1
- // @codonsplice/vue — a useSpliceQL() composable over @codonsplice/wasm.
2
- import { ref } from 'vue'
1
+ // @codonsplice/vue — a useSpliceQL() composable + <SpliceEditor> over @codonsplice/wasm.
2
+ import { ref, defineComponent, h, onMounted, onBeforeUnmount, watch } from 'vue'
3
3
  import { execute as csExecute } from '@codonsplice/wasm/helpers'
4
+ import { mountSpliceEditor } from '@codonsplice/editor'
4
5
 
5
6
  // Re-export the core tooling so apps can `import { useSpliceQL, compile, check }
6
7
  // from '@codonsplice/vue'` without depending on @codonsplice/wasm directly.
7
8
  export { execute, stream, compile, check, ast, initEngine } from '@codonsplice/wasm/helpers'
9
+ // Re-export the editor primitives for apps that want to mount their own view.
10
+ export { spliceqlExtensions, mountSpliceEditor } from '@codonsplice/editor'
11
+
12
+ // A controlled CodeMirror 6 SpliceQL editor. Uses v-model:
13
+ //
14
+ // import { SpliceEditor } from '@codonsplice/vue'
15
+ // <SpliceEditor v-model="query" />
16
+ //
17
+ // Props/events:
18
+ // modelValue — the editor's document (v-model; external changes reconciled)
19
+ // update:modelValue — emitted (docString) on every edit (v-model write-back)
20
+ export const SpliceEditor = defineComponent({
21
+ name: 'SpliceEditor',
22
+ props: { modelValue: { type: String, default: '' } },
23
+ emits: ['update:modelValue'],
24
+ setup(props, { emit }) {
25
+ const host = ref(null)
26
+ let view = null
27
+
28
+ onMounted(() => {
29
+ view = mountSpliceEditor(host.value, {
30
+ doc: props.modelValue,
31
+ onChange: (v) => emit('update:modelValue', v),
32
+ })
33
+ })
34
+
35
+ onBeforeUnmount(() => {
36
+ if (view) { view.destroy(); view = null }
37
+ })
38
+
39
+ // Reconcile an external modelValue change without clobbering live typing.
40
+ watch(() => props.modelValue, (value) => {
41
+ if (!view) return
42
+ const current = view.state.doc.toString()
43
+ if (value !== current) {
44
+ view.dispatch({ changes: { from: 0, to: current.length, insert: value ?? '' } })
45
+ }
46
+ })
47
+
48
+ return () => h('div', { ref: host })
49
+ },
50
+ })
8
51
 
9
52
  export function useSpliceQL() {
10
53
  const result = ref(null)
package/vue/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@codonsplice/vue",
3
- "version": "0.2.3",
3
+ "version": "0.2.4",
4
4
  "type": "module",
5
5
  "main": "index.js",
6
- "dependencies": { "@codonsplice/wasm": "^0.2.3" },
6
+ "dependencies": { "@codonsplice/wasm": "^0.2.4", "@codonsplice/editor": "^0.2.4" },
7
7
  "peerDependencies": { "vue": "*" },
8
8
  "license": "MIT"
9
9
  }