Skip to content

Commit

Permalink
+++
Browse files Browse the repository at this point in the history
  • Loading branch information
Offirmo committed Nov 17, 2024
1 parent 1a0476d commit 1f6d552
Show file tree
Hide file tree
Showing 10 changed files with 129 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -125,11 +125,15 @@ const callbacksⵧto_actions: Partial<WalkerCallbacks<State, RenderingOptionsⵧ
on_type,
}

function renderⵧto_actions($doc: NodeLike, options: RenderingOptionsⵧToActions = DEFAULT_RENDERING_OPTIONSⵧToActions): Action[] {
function renderⵧto_actions($doc: NodeLike, options: Partial<RenderingOptionsⵧToActions> = {}): Action[] {
if (typeof $doc !== 'object') {
return []
}
return walk<State, RenderingOptionsⵧToActions>($doc, callbacksⵧto_actions, options).actions
const full_options: RenderingOptionsⵧToActions = {
...DEFAULT_RENDERING_OPTIONSⵧToActions,
...options,
}
return walk<State, RenderingOptionsⵧToActions>($doc, callbacksⵧto_actions, full_options).actions
}

/////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ function debug_node_short($node: CheckedNode) {

////////////////////////////////////

interface RenderingOptions extends BaseRenderingOptions {}
const DEFAULT_RENDERING_OPTIONS= Object.freeze<RenderingOptions>({
interface RenderingOptionsⵧToDebug extends BaseRenderingOptions {}
const DEFAULT_RENDERING_OPTIONSⵧToDebug= Object.freeze<RenderingOptionsⵧToDebug>({
...DEFAULT_RENDERING_OPTIONSⵧWalk,
})

Expand All @@ -65,7 +65,7 @@ const on_nodeⵧenter = ({$node, $id, depth}: OnNodeEnterParams): State => {
return state
}

const on_nodeⵧexit: WalkerReducer<State, OnNodeExitParams<State>, RenderingOptions> = ({$node, $id, state, depth}) => {
const on_nodeⵧexit: WalkerReducer<State, OnNodeExitParams<State>, RenderingOptionsⵧToDebug> = ({$node, $id, state, depth}) => {
console.log(indent(depth) + `⟨ [on_nodeⵧexit] #${$id}`)
console.log(indent(depth) + ` [state="${state}"]`)
consoleGroupEnd()
Expand All @@ -75,42 +75,42 @@ const on_nodeⵧexit: WalkerReducer<State, OnNodeExitParams<State>, RenderingOpt


// when walking inside the content
const on_concatenateⵧstr: WalkerReducer<State, OnConcatenateStringParams<State>, RenderingOptions> = ({str, state, $node, depth}) => {
const on_concatenateⵧstr: WalkerReducer<State, OnConcatenateStringParams<State>, RenderingOptionsⵧToDebug> = ({str, state, $node, depth}) => {
console.log(indent(depth) + `+ [on_concatenateⵧstr] "${str}"`)
state = state + str
console.log(indent(depth) + ` [state="${state}"]`)
return state
}

const on_concatenateⵧsub_node: WalkerReducer<State, OnConcatenateSubNodeParams<State>, RenderingOptions> = ({state, sub_state, depth, $id, $parent_node}) => {
const on_concatenateⵧsub_node: WalkerReducer<State, OnConcatenateSubNodeParams<State>, RenderingOptionsⵧToDebug> = ({state, sub_state, depth, $id, $parent_node}) => {
console.log(indent(depth) + `+ [on_concatenateⵧsub_node] "${sub_state}"`)
state = state + sub_state
console.log(indent(depth) + ` [state="${state}"]`)
return state
}

const on_filter: WalkerReducer<State, OnFilterParams<State>, RenderingOptions> = ({$filter, $filters, state, $node, depth}) => {
const on_filter: WalkerReducer<State, OnFilterParams<State>, RenderingOptionsⵧToDebug> = ({$filter, $filters, state, $node, depth}) => {
console.log(indent(depth) + ` [on_filter] "${$filter}`)
return state
}

const on_classⵧbefore: WalkerReducer<State, OnClassParams<State>, RenderingOptions> = ({$class, state, $node, depth}) => {
const on_classⵧbefore: WalkerReducer<State, OnClassParams<State>, RenderingOptionsⵧToDebug> = ({$class, state, $node, depth}) => {
console.log(indent(depth) + ` [⟩on_classⵧbefore] .${$class}`)
return state
}
const on_classⵧafter: WalkerReducer<State, OnClassParams<State>, RenderingOptions> = ({$class, state, $node, depth}) => {
const on_classⵧafter: WalkerReducer<State, OnClassParams<State>, RenderingOptionsⵧToDebug> = ({$class, state, $node, depth}) => {
console.log(indent(depth) + ` [⟨on_classⵧafter] .${$class}`)
return state
}

const on_type: WalkerReducer<State, OnTypeParams<State>, RenderingOptions> = ({$type, state, $node, depth}) => {
const on_type: WalkerReducer<State, OnTypeParams<State>, RenderingOptionsⵧToDebug> = ({$type, state, $node, depth}) => {
console.log(indent(depth) + ` [on_type] "${$type}" ${$node.$classes}`)
return state
}

////////////////////////////////////

const callbacksⵧto_debug: Partial<WalkerCallbacks<State, RenderingOptions>> = {
const callbacksⵧto_debug: Partial<WalkerCallbacks<State, RenderingOptionsⵧToDebug>> = {
on_rootⵧenter,
on_rootⵧexit,

Expand Down Expand Up @@ -142,13 +142,18 @@ const callbacksⵧto_debug: Partial<WalkerCallbacks<State, RenderingOptions>> =
},
}

function renderⵧto_debug($doc: Node, options: RenderingOptions = DEFAULT_RENDERING_OPTIONS): string {
return walk<State, RenderingOptions>($doc, callbacksⵧto_debug, options)
function renderⵧto_debug($doc: Node, options: Partial<RenderingOptionsⵧToDebug> = {}): string {
const full_options: RenderingOptionsⵧToDebug = {
...DEFAULT_RENDERING_OPTIONSⵧToDebug,
...options,
}
return walk<State, RenderingOptionsⵧToDebug>($doc, callbacksⵧto_debug, full_options)
}

/////////////////////////////////////////////////

export {
DEFAULT_RENDERING_OPTIONSⵧToDebug,
callbacksⵧto_debug,
renderⵧto_debug,
}
Original file line number Diff line number Diff line change
Expand Up @@ -144,10 +144,18 @@ const callbacksⵧto_html: Partial<WalkerCallbacks<State, RenderingOptionsⵧToH
on_nodeⵧexit,
}

function renderⵧto_html($doc: Node, options: RenderingOptionsⵧToHtml = DEFAULT_RENDERING_OPTIONSⵧToHtml): string {
return '<div class="o⋄rich-text o⋄children-spacing⁚flow">\n '
+ walk<State, RenderingOptionsⵧToHtml>($doc, callbacksⵧto_html, options).str
+ '\n</div>\n'
function renderⵧto_html($doc: Node, options: Partial<RenderingOptionsⵧToHtml> = {}): string {
const full_options: RenderingOptionsⵧToHtml = {
...DEFAULT_RENDERING_OPTIONSⵧToHtml,
...options,
}

// TODO review classes
return `
<div class="o⋄rich-text o⋄children-spacing⁚flow">
${walk<State, RenderingOptionsⵧToHtml>($doc, callbacksⵧto_html, full_options).str}
</div>
`
}

/////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,17 @@ const callbacksⵧto_text: Partial<WalkerCallbacks<State, RenderingOptionsⵧToT

function renderⵧto_text(
$doc: Node,
options: RenderingOptionsⵧToText = DEFAULT_RENDERING_OPTIONSⵧToText,
options: Partial<RenderingOptionsⵧToText> = {},
callback_overrides: Partial<WalkerCallbacks<State, RenderingOptionsⵧToText>> = {},
): string {
const full_options: RenderingOptionsⵧToText = {
...DEFAULT_RENDERING_OPTIONSⵧToText,
...options,
}
return walk<State, RenderingOptionsⵧToText>($doc, {
...callbacksⵧto_text,
...callback_overrides,
}, options).str
}, full_options).str
}

/////////////////////////////////////////////////
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@ import * as RichText from '../index.js'
/////////////////////////////////////////////////

describe(`${LIB} -- renderers -- to text`, () => {
let rendering_options = RichText.DEFAULT_RENDERING_OPTIONSⵧToText
let rendering_options = {}
beforeEach(() => {
rendering_options = {
...RichText.DEFAULT_RENDERING_OPTIONSⵧToText,
}
rendering_options = {}
})

const $DEMOⵧSIMPLE = (() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import {

import { normalizeꓽnode } from '../utils/normalize.js'
import { promoteꓽto_node } from '../utils/promote.js'
import { Action, EmbeddedReducerAction, HyperlinkAction, ReducerAction, RenderingOptionsⵧToActions } from './to_actions'

/////////////////////////////////////////////////
// "walk" is the foundation on which all the renderer are based
Expand Down Expand Up @@ -268,8 +267,11 @@ function _walk_content<State, RenderingOptions extends BaseRenderingOptions>(
return { $content: `{{??${sub_node_id}??}}` }
}

//console.error($node, { $content, sub_node_id })
throw new Error(`${LIB}: syntax error in content "${$content}", it's referencing an unknown sub-node "${sub_node_id}"!`)
if (true) {
console.error('shouldꓽrecover_from_unknown_sub_nodes FAILURE',)
console.error($node, { $content, sub_node_id })
}
throw new Error(`${LIB}: syntax error in content "${$content}", it's referencing an unknown sub-node "${sub_node_id}"! (recover mode = ${options.shouldꓽrecover_from_unknown_sub_nodes})`)
})())

let sub_state = _walk($sub_node, callbacks, options, {
Expand Down Expand Up @@ -437,17 +439,26 @@ function _walk<State, RenderingOptions extends BaseRenderingOptions>(
function walk<State, RenderingOptions extends BaseRenderingOptions>(
$raw_node: Readonly<Node>,
raw_callbacks: Readonly<Partial<WalkerCallbacks<State, RenderingOptions>>>,
options: Readonly<RenderingOptions> = {} as any,
options: RenderingOptions, // this internal fn can't default unknown type, so we expect the caller to give us full options
) {
if (!Object.keys(raw_callbacks).every(k => k === 'resolve_unknown_subnode' || k.startsWith('on_')))
console.warn(`${LIB} Unexpected unrecognized callbacks, check the API!`)
assert(
Object.keys(raw_callbacks).every(k => k === 'resolve_unknown_subnode' || k.startsWith('on_')),
`${LIB}[walk]: custom callbacks should match the expected format, check the API!`
)

const callbacks: WalkerCallbacks<State, RenderingOptions> = {
..._getꓽcallbacksⵧdefault<State, RenderingOptions>(),
...raw_callbacks as any as WalkerCallbacks<State, RenderingOptions>,
}

assert(
// detect incorrectly built options (actual issue before rewrite in 2024)
options.shouldꓽrecover_from_unknown_sub_nodes !== undefined,
`${LIB}[walk]: options should be a fully initialized options object!`
)

const $root_node = normalizeꓽnode($raw_node)

return _walk($root_node, callbacks, options, {
$parent_node: null,
$id: 'root',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,31 @@ import { LIB } from '../consts.js'
/////////////////////////////////////////////////

import * as RichText from '../index.js'
import { walk, WalkerCallbacks } from './walk.js'
import { BaseRenderingOptions, Node } from '../index.js'
import {
walk,
type WalkerCallbacks,
} from './walk.js'
import {
type BaseRenderingOptions,
type Node,
} from '../index.js'

describe(`${LIB} -- renderers -- walker (internal)`, function () {

interface State {}
interface Options extends BaseRenderingOptions {}
const callbacks: Partial<WalkerCallbacks<State, Options>> = {
on_nodeⵧenter() { return {} as State },
}

let rendering_options: Options = {
shouldꓽrecover_from_unknown_sub_nodes: false,
}
beforeEach(() => {
rendering_options = {
shouldꓽrecover_from_unknown_sub_nodes: false,
}
})

describe('walking through all nodes in order', function () {

it('should work')
Expand Down Expand Up @@ -76,7 +90,7 @@ describe(`${LIB} -- renderers -- walker (internal)`, function () {
},
}

expect(() => walk<State, Options>($doc, {...callbacks})).to.throw('unknown sub-node')
expect(() => walk<State, Options>($doc, {...callbacks}, rendering_options)).to.throw('unknown sub-node')
})

it('should work -- handling missing -- auto recovery -- placeholder', () => {
Expand Down Expand Up @@ -160,7 +174,7 @@ describe(`${LIB} -- renderers -- walker (internal)`, function () {
const $doc = {
$content: '⎨⎨foo',
}
expect(() => walk<State, Options>($doc, {...callbacks})).to.throw('unmatched')
expect(() => walk<State, Options>($doc, {...callbacks}, rendering_options)).to.throw('unmatched')
})
it('should detect unmatched ⎨⎨⎬⎬ -- ⎨⎨ 2', () => {
const $doc = {
Expand All @@ -169,15 +183,15 @@ describe(`${LIB} -- renderers -- walker (internal)`, function () {
'foo': {}
},
}
expect(() => walk<State, Options>($doc, {...callbacks})).to.throw('unmatched')
expect(() => walk<State, Options>($doc, {...callbacks}, rendering_options)).to.throw('unmatched')
})

it('should detect unmatched ⎨⎨⎬⎬ -- ⎬⎬ 1', () => {

const $doc = {
$content: 'foo⎬⎬',
}
expect(() => walk<State, Options>($doc, {...callbacks})).to.throw('unmatched')
expect(() => walk<State, Options>($doc, {...callbacks}, rendering_options)).to.throw('unmatched')
})
it('should detect unmatched ⎨⎨⎬⎬ -- ⎬⎬ 2a', () => {

Expand All @@ -187,7 +201,7 @@ describe(`${LIB} -- renderers -- walker (internal)`, function () {
'foo': {}
},
}
expect(() => walk<State, Options>($doc, {...callbacks})).to.throw('unmatched')
expect(() => walk<State, Options>($doc, {...callbacks}, rendering_options)).to.throw('unmatched')
})
it('should detect unmatched ⎨⎨⎬⎬ -- ⎬⎬ 2b', () => {

Expand All @@ -197,7 +211,7 @@ describe(`${LIB} -- renderers -- walker (internal)`, function () {
'foo': {}
},
}
expect(() => walk<State, Options>($doc, {...callbacks})).to.throw('unmatched')
expect(() => walk<State, Options>($doc, {...callbacks}, rendering_options)).to.throw('unmatched')
})

it('should detect reversed ⎨⎨⎬⎬', () => {
Expand All @@ -208,7 +222,7 @@ describe(`${LIB} -- renderers -- walker (internal)`, function () {
'foo': {}
},
}
expect(() => walk<State, Options>($doc, {...callbacks})).to.throw('unmatched')
expect(() => walk<State, Options>($doc, {...callbacks}, rendering_options)).to.throw('unmatched')
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,12 @@ interface Builder {
// node ref is auto added into content
pushNode(node: Node, options?: CommonOptions): Builder

// nothing is added in content
// NOTHING is added into content
// useful for
// 1. lists
// 2. manual stuff
pushRawNode(node: Node, options?: CommonOptions): Builder
pushRawNodes(nodes: { [id: string]: Node }): Builder // batch version
pushRawNode(node: CheckedNode['$sub'][string], options?: CommonOptions): Builder
pushRawNodes(nodes: CheckedNode['$sub']): Builder // batch version

pushInlineFragment(str: string, options?: CommonOptions): Builder
pushBlockFragment(str: string, options?: CommonOptions): Builder
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,10 @@ function _refresh_achievements(state: Immutable<State>): Immutable<State> {
engagement = enqueueEngagement(engagement,
getꓽengagement_template(EngagementTemplateKey.achievement_unlocked),
{
icon,
name,
$sub: {
icon,
name,
},
},
)
}
Expand Down
Loading

0 comments on commit 1f6d552

Please sign in to comment.