Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"lint:fix:danger": "oxlint . --fix-dangerously",
"format": "oxfmt --check",
"format:fix": "oxfmt",
"typecheck": "tsc --noEmit && pnpm run -F @markput/website check",
"typecheck": "pnpm -r run typecheck",
"clean": "git clean -xdf",
"clean:dry": "git clean -xdn",
"preinstall": "npx only-allow pnpm",
Expand Down
2 changes: 2 additions & 0 deletions packages/common/core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"./styles.module.css": "./styles.module.css"
},
"scripts": {
"typecheck": "tsc --noEmit",
"build": "vite build",
"build:watch": "vite build -w",
"test": "vitest run",
Expand All @@ -24,6 +25,7 @@
"@faker-js/faker": "catalog:",
"@vitest/coverage-v8": "catalog:",
"@vitest/ui": "catalog:",
"typescript": "catalog:",
"vite": "catalog:",
"vitest": "catalog:"
}
Expand Down
6 changes: 3 additions & 3 deletions packages/common/core/src/features/store/Store.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {defineState, defineEvents, type UseHookFactory} from '../../shared/classes'
import {defineState, defineEvents, type UseHookFactory, type StateObject} from '../../shared/classes'
import {KeyGenerator} from '../../shared/classes/KeyGenerator'
import {NodeProxy} from '../../shared/classes/NodeProxy'
import type {MarkputHandler, MarkputState, OverlayMatch} from '../../shared/types'
Expand All @@ -22,7 +22,7 @@ export class Store {
input: new NodeProxy(undefined, this),
}

readonly state: ReturnType<typeof defineState<MarkputState>>
readonly state: StateObject<MarkputState>

readonly events = defineEvents<{
change: void
Expand All @@ -49,7 +49,7 @@ export class Store {
readonly lifecycle = new Lifecycle(this)

constructor(options: StoreOptions) {
this.state = defineState(
this.state = defineState<MarkputState>(
{
tokens: [],
parser: undefined,
Expand Down
11 changes: 6 additions & 5 deletions packages/common/core/src/shared/classes/defineState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,24 @@ import {Reactive} from './Reactive'

/**
* Framework adapters can return any reactive wrapper from `use`.
* React returns plain values, while Vue can return `Ref<T>`.
* The actual return type of `use()` is overridden per-framework via module augmentation.
* React returns plain T, Vue augments Signal<T> so that `use()` returns Ref<T>.
*/
export type UseHookFactory = <T>(signal: Signal<T>) => () => any
export type UseHookFactory = <T>(signal: Signal<T>) => () => unknown

export type Signal<T> = {
export interface Signal<T> {
get(): T
set(value: T): void
on(fn: (value: T) => void): () => void
use: () => T
use(): T
}

function createSignal<T>(reactive: Reactive<T>, createUseHook: UseHookFactory): Signal<T> {
const signal = {} as Signal<T>
signal.get = () => reactive.get()
signal.set = (value: T) => reactive.set(value)
signal.on = (fn: (value: T) => void) => reactive.on(fn)
signal.use = createUseHook(signal)
signal.use = createUseHook(signal) as Signal<T>['use']

return signal
}
Expand Down
2 changes: 1 addition & 1 deletion packages/common/core/src/shared/classes/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export {Reactive} from './Reactive'
export type {Signal, UseHookFactory} from './defineState'
export type {Signal, UseHookFactory, StateObject} from './defineState'
export {defineState} from './defineState'
export type {Emitter} from './defineEvents'
export {defineEvents} from './defineEvents'
Expand Down
1 change: 1 addition & 0 deletions packages/react/markput/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
}
},
"scripts": {
"typecheck": "tsc --noEmit",
"build": "vite build && tsc && node prepack.js",
"publish": "pnpm publish dist --no-git-checks --json --access public --provenance"
},
Expand Down
1 change: 1 addition & 0 deletions packages/vue/markput/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
}
},
"scripts": {
"typecheck": "vue-tsc --noEmit",
"build": "vite build && vue-tsc --declaration --emitDeclarationOnly && node prepack.js",
"publish": "pnpm publish dist --no-git-checks --json --access public --provenance"
},
Expand Down
14 changes: 7 additions & 7 deletions packages/vue/markput/src/components/BlockContainer.vue
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
<script setup lang="ts">
import type {CoreSlotProps, CoreSlots, Token as CoreToken} from '@markput/core'
import {splitTokensIntoBlocks, reorderBlocks, parseWithParser} from '@markput/core'
import {computed, type Ref} from 'vue'
import {computed} from 'vue'

import {useStore} from '../lib/hooks/useStore'
import {resolveSlot, resolveSlotProps} from '../lib/utils/resolveSlot'
import DraggableBlock from './DraggableBlock.vue'
import Token from './Token.vue'

const store = useStore()
const tokens = store.state.tokens.use() as unknown as Ref<CoreToken[]>
const slots = store.state.slots.use() as unknown as Ref<CoreSlots | undefined>
const slotProps = store.state.slotProps.use() as unknown as Ref<CoreSlotProps | undefined>
const tokens = store.state.tokens.use()
const slots = store.state.slots.use()
const slotProps = store.state.slotProps.use()
const className = store.state.className.use()
const style = store.state.style.use()
const readOnly = store.state.readOnly.use() as unknown as Ref<boolean>
const value = store.state.value.use() as unknown as Ref<string | undefined>
const onChange = store.state.onChange.use() as unknown as Ref<((v: string) => void) | undefined>
const readOnly = store.state.readOnly.use()
const value = store.state.value.use()
const onChange = store.state.onChange.use()
const key = store.key

const containerTag = computed(() => resolveSlot('container', slots.value))
Expand Down
12 changes: 6 additions & 6 deletions packages/vue/markput/src/components/Container.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import type {CoreSlotProps, CoreSlots, StyleProperties, Token as CoreToken} from '@markput/core'
import {computed, defineComponent, h, type Ref} from 'vue'
import {computed, defineComponent, h} from 'vue'

import {useStore} from '../lib/hooks/useStore'
import {resolveSlot, resolveSlotProps} from '../lib/utils/resolveSlot'
Expand All @@ -9,11 +9,11 @@ import Token from './Token.vue'
export default defineComponent({
setup() {
const store = useStore()
const tokens = store.state.tokens.use() as unknown as Ref<CoreToken[]>
const slots = store.state.slots.use() as unknown as Ref<CoreSlots | undefined>
const slotProps = store.state.slotProps.use() as unknown as Ref<CoreSlotProps | undefined>
const className = store.state.className.use() as unknown as Ref<string | undefined>
const style = store.state.style.use() as unknown as Ref<StyleProperties | undefined>
const tokens = store.state.tokens.use()
const slots = store.state.slots.use()
const slotProps = store.state.slotProps.use()
const className = store.state.className.use()
const style = store.state.style.use()
const key = store.key

const containerTag = computed(() => resolveSlot('container', slots.value))
Expand Down
2 changes: 1 addition & 1 deletion packages/vue/markput/src/components/MarkRenderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Token from './Token.vue'
const store = useStore()
const tokenRef = inject(TOKEN_KEY)!
const node = tokenRef.value as MarkToken
const optionsRef = store.state.options.use() as unknown as Ref<Option[] | undefined>
const optionsRef = store.state.options.use() as Ref<Option[] | undefined>
const MarkRef = store.state.Mark.use() as Ref<Component | undefined>
const key = store.key

Expand Down
4 changes: 2 additions & 2 deletions packages/vue/markput/src/components/OverlayRenderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import type {Option} from '../types'
import Suggestions from './Suggestions/Suggestions.vue'

const store = useStore()
const overlayMatchRef = store.state.overlayMatch.use() as unknown as Ref<OverlayMatch<Option> | undefined>
const OverlayRef = store.state.Overlay.use() as unknown as Ref<Component | undefined>
const overlayMatchRef = store.state.overlayMatch.use() as Ref<OverlayMatch<Option> | undefined>
const OverlayRef = store.state.Overlay.use() as Ref<Component | undefined>

const overlayKey = computed(() => (overlayMatchRef.value ? store.key.get(overlayMatchRef.value.option) : undefined))

Expand Down
8 changes: 4 additions & 4 deletions packages/vue/markput/src/components/TextSpan.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import type {CoreSlotProps, CoreSlots} from '@markput/core'
import {inject, ref, computed, watch, onMounted, type Ref} from 'vue'
import {inject, ref, computed, watch, onMounted} from 'vue'

import {useStore} from '../lib/hooks/useStore'
import {TOKEN_KEY} from '../lib/providers/tokenKey'
Expand All @@ -11,9 +11,9 @@ const tokenRef = inject(TOKEN_KEY)!
const token = tokenRef.value
const elRef = ref<HTMLSpanElement | null>(null)

const readOnly = store.state.readOnly.use() as unknown as Ref<boolean>
const slots = store.state.slots.use() as unknown as Ref<CoreSlots | undefined>
const slotProps = store.state.slotProps.use() as unknown as Ref<CoreSlotProps | undefined>
const readOnly = store.state.readOnly.use()
const slots = store.state.slots.use()
const slotProps = store.state.slotProps.use()
const spanTag = computed(() => resolveSlot('span', slots.value))
const spanProps = computed(() => resolveSlotProps('span', slotProps.value))

Expand Down
4 changes: 2 additions & 2 deletions packages/vue/markput/src/lib/hooks/createUseHook.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {Signal} from '@markput/core'
import type {Signal, UseHookFactory} from '@markput/core'
import {type Ref, shallowRef} from 'vue'

export const createUseHook =
export const createUseHook: UseHookFactory =
<T>(signal: Signal<T>) =>
(): Ref<T> => {
const value = shallowRef(signal.get()) as Ref<T>
Expand Down
8 changes: 4 additions & 4 deletions packages/vue/markput/src/lib/hooks/useCoreFeatures.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {Store} from '@markput/core'
import {onMounted, onUnmounted, watch, type Ref} from 'vue'
import {onMounted, onUnmounted, watch} from 'vue'

import type {Option} from '../../types'

Expand All @@ -14,9 +14,9 @@ export function useCoreFeatures(store: Store) {
store.lifecycle.disable()
})

const value = store.state.value.use() as unknown as Ref<string | undefined>
const Mark = store.state.Mark.use() as unknown as Ref<unknown>
const coreOptions = store.state.options.use() as unknown as Ref<Option[] | undefined>
const value = store.state.value.use()
const Mark = store.state.Mark.use()
const coreOptions = store.state.options.use()

watch(
[value, coreOptions, Mark],
Expand Down
4 changes: 2 additions & 2 deletions packages/vue/markput/src/lib/hooks/useMark.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type {MarkToken} from '@markput/core'
import {MarkHandler} from '@markput/core'
import {type Ref, inject, ref, watch, onMounted} from 'vue'
import {inject, ref, watch, onMounted} from 'vue'

import {TOKEN_KEY} from '../providers/tokenKey'
import {useStore} from './useStore'
Expand Down Expand Up @@ -40,7 +40,7 @@ export const useMark = <T extends HTMLElement = HTMLElement>(options: MarkOption
}
})

const readOnly = store.state.readOnly.use() as unknown as Ref<boolean>
const readOnly = store.state.readOnly.use()
watch(readOnly, val => {
mark.readOnly = val
})
Expand Down
2 changes: 1 addition & 1 deletion packages/vue/markput/src/lib/hooks/useOverlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export interface OverlayHandler {

export function useOverlay(): OverlayHandler {
const store = useStore()
const matchRef = store.state.overlayMatch.use() as unknown as Ref<OverlayMatch<Option> | undefined>
const matchRef = store.state.overlayMatch.use() as Ref<OverlayMatch<Option> | undefined>

const style = computed(() => {
// Depend on matchRef so position recalculates as user types/moves caret
Expand Down
7 changes: 7 additions & 0 deletions packages/vue/markput/src/lib/hooks/useStore.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import type {Store} from '@markput/core'
import {inject} from 'vue'
import type {Ref} from 'vue'

import {STORE_KEY} from '../providers/storeKey'

declare module '@markput/core' {
interface Signal<T> {
use(): Ref<T>
}
}

export function useStore(): Store {
const store = inject(STORE_KEY)
if (!store) {
Expand Down
2 changes: 1 addition & 1 deletion packages/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"check": "astro check",
"typecheck": "astro check",
"astro": "astro"
},
"dependencies": {
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.