Skip to content

Commit

Permalink
wip: migrate all plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
petyosi committed Dec 28, 2023
1 parent 261fc48 commit 4b646a7
Show file tree
Hide file tree
Showing 18 changed files with 748 additions and 984 deletions.
101 changes: 31 additions & 70 deletions src/plugins/codeblock/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { CodeBlockVisitor } from './CodeBlockVisitor'
import { realmPlugin, system } from '../../gurx'
import { MdastCodeVisitor } from './MdastCodeVisitor'
import { coreSystem } from '../core'
import { Appender, addActivePlugin$, addExportVisitor$, addImportVisitor$, addLexicalNode$, insertDecoratorNode$ } from '../core'
import { $createCodeBlockNode, CodeBlockNode, CreateCodeBlockNodeOptions } from './CodeBlockNode'
import { VoidEmitter } from '../../utils/voidEmitter'
import { Cell, Signal, map, withLatestFrom } from '@mdxeditor/gurx'
import { realmPlugin } from '@/RealmWithPlugins'

export type { CodeBlockEditorContextValue, CreateCodeBlockNodeOptions } from './CodeBlockNode'
export { useCodeBlockEditorContext } from './CodeBlockNode'
Expand Down Expand Up @@ -57,52 +58,24 @@ export interface CodeBlockEditorDescriptor {
Editor: React.ComponentType<CodeBlockEditorProps>
}

/**
* @internal
*/
export const codeBlockSystem = system(
(r, [{ insertDecoratorNode }]) => {
const codeBlockEditorDescriptors = r.node<CodeBlockEditorDescriptor[]>([])
const appendCodeBlockEditorDescriptor = r.node<CodeBlockEditorDescriptor>()
const insertCodeBlock = r.node<Partial<CreateCodeBlockNodeOptions>>()
const defaultCodeBlockLanguage = r.node<string>('')

r.link(
r.pipe(
insertCodeBlock,
r.o.withLatestFrom(defaultCodeBlockLanguage),
r.o.map(
([payload, defaultCodeBlockLanguage]) =>
() =>
$createCodeBlockNode({ language: defaultCodeBlockLanguage, ...payload })
)
),
insertDecoratorNode
)

r.link(
r.pipe(
appendCodeBlockEditorDescriptor,
r.o.withLatestFrom(codeBlockEditorDescriptors),
r.o.map(([newValue, values]) => {
if (values.includes(newValue)) {
return values
}
return [...values, newValue]
})
),
codeBlockEditorDescriptors
)
export const codeBlockEditorDescriptors$ = Cell<CodeBlockEditorDescriptor[]>([])
export const defaultCodeBlockLanguage$ = Cell<string>('')
export const insertCodeBlock$ = Signal<Partial<CreateCodeBlockNodeOptions>>((r) => {
r.link(
r.pipe(
insertCodeBlock$,
withLatestFrom(defaultCodeBlockLanguage$),
map(
([payload, defaultCodeBlockLanguage]) =>
() =>
$createCodeBlockNode({ language: defaultCodeBlockLanguage, ...payload })
)
),
insertDecoratorNode$
)
})

return {
codeBlockEditorDescriptors,
defaultCodeBlockLanguage,
appendCodeBlockEditorDescriptor,
insertCodeBlock
}
},
[coreSystem]
)
export const appendCodeBlockEditorDescriptor$ = Appender(codeBlockEditorDescriptors$)

/**
* The parameters passed to the codeBlockPlugin initializer.
Expand All @@ -118,30 +91,18 @@ export interface CodeBlockPluginParams {
defaultCodeBlockLanguage?: string
}

export const [
/**
* @internal
*/
codeBlockPlugin,

/**
* @internal
*/
codeBlockPluginHooks
] = realmPlugin({
id: 'codeblock',
systemSpec: codeBlockSystem,

applyParamsToSystem(realm, params?: CodeBlockPluginParams) {
realm.pubKey('defaultCodeBlockLanguage', params?.defaultCodeBlockLanguage || '')
export const codeBlockPlugin = realmPlugin({
update(realm, params?: CodeBlockPluginParams) {
realm.pub(defaultCodeBlockLanguage$, params?.defaultCodeBlockLanguage || '')
},

init: (realm, params: CodeBlockPluginParams) => {
realm.pubKey('codeBlockEditorDescriptors', params?.codeBlockEditorDescriptors || [])
// import
realm.pubKey('addImportVisitor', MdastCodeVisitor)
// export
realm.pubKey('addLexicalNode', CodeBlockNode)
realm.pubKey('addExportVisitor', CodeBlockVisitor)
init(realm, params: CodeBlockPluginParams) {
realm.pubIn({
[addActivePlugin$]: 'codeblock',
[codeBlockEditorDescriptors$]: params?.codeBlockEditorDescriptors || [],
[addImportVisitor$]: MdastCodeVisitor,
[addLexicalNode$]: CodeBlockNode,
[addExportVisitor$]: CodeBlockVisitor
})
}
})
67 changes: 24 additions & 43 deletions src/plugins/codemirror/index.tsx
Original file line number Diff line number Diff line change
@@ -1,58 +1,39 @@
import { realmPlugin, system } from '../../gurx'
import { coreSystem } from '../core'
import { codeBlockSystem } from '../codeblock'
import { realmPlugin } from '@/RealmWithPlugins'
import { Cell, Signal, map } from '@mdxeditor/gurx'
import { appendCodeBlockEditorDescriptor$, insertCodeBlock$ } from '../codeblock'
import { CodeMirrorEditor } from './CodeMirrorEditor'

const defaultCodeBlockLanguages: Record<string, string> = {
export const codeBlockLanguages$ = Cell({
js: 'JavaScript',
ts: 'TypeScript',
tsx: 'TypeScript (React)',
jsx: 'JavaScript (React)',
css: 'CSS'
}

/** @internal */
export const codeMirrorSystem = system(
(r, [, { insertCodeBlock }]) => {
const codeBlockLanguages = r.node(defaultCodeBlockLanguages)
const insertCodeMirror = r.node<{ language: string; code: string }>()

r.link(
r.pipe(
insertCodeMirror,
r.o.map(({ language, code }) => {
return {
code: code,
language,
meta: ''
}
})
),
insertCodeBlock
)
})

return {
codeBlockLanguages,
insertCodeMirror
}
},
[coreSystem, codeBlockSystem]
)
export const insertCodeMirror$ = Signal<{ language: string; code: string }>((r) => {
r.link(
r.pipe(
insertCodeMirror$,
map(({ language, code }) => {
return {
code: code,
language,
meta: ''
}
})
),
insertCodeBlock$
)
})

export const [
/** @internal */
codeMirrorPlugin,
/** @internal */
codeMirrorHooks
] = realmPlugin({
id: 'codemirror',
systemSpec: codeMirrorSystem,
applyParamsToSystem(r, params: { codeBlockLanguages: Record<string, string> }) {
r.pubKey('codeBlockLanguages', params.codeBlockLanguages)
export const codeMirrorPlugin = realmPlugin({
update(r, params: { codeBlockLanguages: Record<string, string> }) {
r.pub(codeBlockLanguages$, params.codeBlockLanguages)
},

init(r, { codeBlockLanguages }) {
r.pubKey('appendCodeBlockEditorDescriptor', {
r.pub(appendCodeBlockEditorDescriptor$, {
match(language, meta) {
return codeBlockLanguages.hasOwnProperty(language) && meta === ''
},
Expand Down
35 changes: 32 additions & 3 deletions src/plugins/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ export const iconComponentFor$ = Cell<(name: IconKey) => React.ReactNode>((name:
throw new Error(`No icon component for ${name}`)
})

function Appender<T>(cell$: NodeRef<T[]>, init?: (r: Realm, sig$: NodeRef<T | T[]>) => void) {
export function Appender<T>(cell$: NodeRef<T[]>, init?: (r: Realm, sig$: NodeRef<T | T[]>) => void) {
return Signal<T | T[]>((r, sig$) => {
r.changeWith(cell$, sig$, (values, newValue) => {
if (!Array.isArray(newValue)) {
Expand Down Expand Up @@ -508,8 +508,37 @@ export const insertDecoratorNode$ = Signal<() => DecoratorNode<unknown>>((r) =>
})

export type ViewMode = 'rich-text' | 'source' | 'diff'
export const viewMode$ = Cell<ViewMode>('rich-text')
export const markdownSourceEditorValue$ = Cell('')

export const viewMode$ = Cell<ViewMode>('rich-text', (r) => {
r.sub(
r.pipe(
viewMode$,
scan(
(prev, next) => {
return {
current: prev.next,
next
}
},
{ current: 'rich-text' as ViewMode, next: 'rich-text' as ViewMode }
),
withLatestFrom(markdownSourceEditorValue$)
),
([{ current }, markdownSourceFromEditor]) => {
if (current === 'source' || current === 'diff') {
r.pub(setMarkdown$, markdownSourceFromEditor)
}
}
)
})

export const markdownSourceEditorValue$ = Cell('', (r) => {
r.link(markdown$, markdownSourceEditorValue$)
r.link(markdownSourceEditorValue$, markdownSignal$)
})

export const activePlugins$ = Cell<string[]>([])
export const addActivePlugin$ = Appender(activePlugins$)

interface CorePluginParams {
initialMarkdown: string
Expand Down
68 changes: 14 additions & 54 deletions src/plugins/diff-source/index.tsx
Original file line number Diff line number Diff line change
@@ -1,69 +1,29 @@
import { Extension } from '@codemirror/state'
import { realmPlugin, system } from '../../gurx'
import { coreSystem } from '../core'
import { ViewMode, addEditorWrapper$, viewMode$ } from '../core'
import { DiffSourceWrapper } from './DiffSourceWrapper'
import { Cell } from '@mdxeditor/gurx'
import { realmPlugin } from '@/RealmWithPlugins'

/** @internal */
export type ViewMode = 'rich-text' | 'source' | 'diff'

/** @internal */
export const diffSourceSystem = system(
(r, [{ markdown, setMarkdown, markdownSignal }]) => {
const diffMarkdown = r.node('')
const markdownSourceEditorValue = r.node('')
const cmExtensions = r.node<Extension[]>([])

r.link(markdown, markdownSourceEditorValue)
r.link(markdownSourceEditorValue, markdownSignal)
const viewMode = r.node<ViewMode>('rich-text')

r.sub(
r.pipe(
viewMode,
r.o.scan(
(prev, next) => {
return {
current: prev.next,
next
}
},
{ current: 'rich-text' as ViewMode, next: 'rich-text' as ViewMode }
),
r.o.withLatestFrom(markdownSourceEditorValue)
),
([{ current }, markdownSourceFromEditor]) => {
if (current === 'source' || current === 'diff') {
r.pub(setMarkdown, markdownSourceFromEditor)
}
}
)
return { viewMode, diffMarkdown, markdownSourceEditorValue, cmExtensions }
},
[coreSystem]
)
export const diffMarkdown$ = Cell('')
export const cmExtensions$ = Cell<Extension[]>([])

export interface DiffSourcePluginParams {
viewMode?: ViewMode
diffMarkdown?: string
codeMirrorExtensions?: Extension[]
}

export const [
/** @internal */
diffSourcePlugin,
/** @internal */
diffSourcePluginHooks
] = realmPlugin({
id: 'diff-source',
systemSpec: diffSourceSystem,
applyParamsToSystem: (r, params?: DiffSourcePluginParams) => {
r.pubKey('diffMarkdown', params?.diffMarkdown || '')
export const diffSourcePlugin = realmPlugin({
update: (r, params?: DiffSourcePluginParams) => {
r.pub(diffMarkdown$, params?.diffMarkdown || '')
},

init(r, params?: DiffSourcePluginParams) {
r.pubKey('diffMarkdown', params?.diffMarkdown || '')
r.pubKey('cmExtensions', params?.codeMirrorExtensions || [])
r.pubKey('addEditorWrapper', DiffSourceWrapper)
r.pubKey('viewMode', params?.viewMode || 'rich-text')
r.pubIn({
[diffMarkdown$]: params?.diffMarkdown || '',
[cmExtensions$]: params?.codeMirrorExtensions || [],
[addEditorWrapper$]: DiffSourceWrapper,
[viewMode$]: params?.viewMode || 'rich-text'
})
}
})

0 comments on commit 4b646a7

Please sign in to comment.