Skip to content

Commit 10d5d40

Browse files
committed
body returns HtmlResult
1 parent a2984af commit 10d5d40

10 files changed

+149
-78
lines changed

app-ugc/src/setBody.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import { assertNever } from 'shared'
88
import { resizeIframe } from './registerServiceWorker'
99
import diff from 'micromorph'
10+
import { getOk } from 'shared-dom'
1011

1112
self.addEventListener('message', async (event) => {
1213
const data = event.data as unknown
@@ -43,7 +44,9 @@ async function buildHtml(i: RenderBodyInput) {
4344
switch (i.tag) {
4445
case 'template': {
4546
const template = i.template
46-
const result = (await appMessenger.renderTemplate(template))[i.index]
47+
const result = getOk(
48+
(await appMessenger.renderTemplate(template))[i.index],
49+
)
4750
if (result == null) {
4851
return {
4952
body: `Error rendering Template #${i.index}".`,
@@ -57,7 +60,9 @@ async function buildHtml(i: RenderBodyInput) {
5760
}
5861
}
5962
case 'card': {
60-
const frontBack = await appMessenger.html(i.card, i.note, i.template)
63+
const frontBack = getOk(
64+
await appMessenger.html(i.card, i.note, i.template),
65+
)
6166
if (frontBack == null) {
6267
return { body: 'Card is invalid!' }
6368
}

app/src/components/cardsTable.tsx

+7-3
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import { LicenseManager } from 'ag-grid-enterprise'
2222
import { db } from '../db'
2323
import { assertNever } from 'shared'
2424
import { agGridTheme } from '../globalState'
25-
import { Upload } from 'shared-dom'
25+
import { Upload, getOk } from 'shared-dom'
2626
import { C } from '../topLevelAwait'
2727
import FiltersTable from './filtersTable'
2828
import './cardsTable.css'
@@ -55,15 +55,19 @@ const columnDefs: Array<ColDef<NoteCard>> = [
5555
headerName: 'Short Front',
5656
valueGetter: (x) => {
5757
if (x.data != null) {
58-
return C.body(x.data.card, x.data.note, x.data.template, true)?.at(0)
58+
return getOk(
59+
C.body(x.data.card, x.data.note, x.data.template, true),
60+
)?.at(0)
5961
}
6062
},
6163
},
6264
{
6365
headerName: 'Short Back',
6466
valueGetter: (x) => {
6567
if (x.data != null) {
66-
return C.body(x.data.card, x.data.note, x.data.template, true)?.at(1)
68+
return getOk(
69+
C.body(x.data.card, x.data.note, x.data.template, true),
70+
)?.at(1)
6771
}
6872
},
6973
},

app/src/components/editChildTemplate.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import ResizingIframe from './resizingIframe'
4040
import { C } from '../topLevelAwait'
4141
import { oneDark } from '@codemirror/theme-one-dark'
4242
import { theme } from '../globalState'
43-
import { htmlTemplateLanguage, templateLinter } from 'shared-dom'
43+
import { getOk, htmlTemplateLanguage, templateLinter } from 'shared-dom'
4444

4545
const EditChildTemplate: VoidComponent<{
4646
template: Template
@@ -88,7 +88,7 @@ const EditChildTemplate: VoidComponent<{
8888
frontView?.destroy()
8989
backView?.destroy()
9090
})
91-
const short = () => C.renderTemplate(props.template, true)[props.i]
91+
const short = () => getOk(C.renderTemplate(props.template, true)[props.i])
9292
return (
9393
<fieldset class='border-black border p-2'>
9494
<legend>

hub-ugc/src/setBody.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import contentWindowJs from 'iframe-resizer/js/iframeResizer.contentWindow.js?raw' // https://vitejs.dev/guide/assets.html#importing-asset-as-string https://github.com/davidjbradshaw/iframe-resizer/issues/513
22
import { type RenderBodyInput } from 'hub/src/components/resizingIframe'
33
import { assertNever, relativeChar } from 'shared'
4-
import { registerPluginServices } from 'shared-dom'
4+
import { getOk, registerPluginServices } from 'shared-dom'
55

66
const C = await registerPluginServices([])
77

@@ -50,7 +50,7 @@ function buildHtml(i: RenderBodyInput): { body: string; css?: string } {
5050
switch (i.tag) {
5151
case 'template': {
5252
const template = i.template
53-
const result = C.renderTemplate(template)[i.index]
53+
const result = getOk(C.renderTemplate(template)[i.index])
5454
if (result == null) {
5555
return {
5656
body: `Error rendering Template #${i.index}".`,
@@ -64,7 +64,7 @@ function buildHtml(i: RenderBodyInput): { body: string; css?: string } {
6464
}
6565
}
6666
case 'card': {
67-
const frontBack = C.html(i.card, i.note, i.template)
67+
const frontBack = getOk(C.html(i.card, i.note, i.template))
6868
if (frontBack == null) {
6969
return { body: 'Card is invalid!' }
7070
}

shared-dom/src/cardHtml.plugin.test.ts

+7-6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
import { type Plugin } from './plugin.js'
1212
import { registerPluginServices } from './pluginManager.js'
1313
import { strip } from './cardHtml'
14+
import { getOk } from './cardHtml.test.js'
1415

1516
function expectStrippedToBe(html: string, expected: string): void {
1617
const newline = /[\r\n]/g
@@ -70,9 +71,9 @@ test('renderTemplate works with plugin that requires `edit` syntax', async () =>
7071
const c = await registerPluginServices([plugin])
7172
const templates = c.renderTemplate(clozeWithRequiredEdit)
7273
expect(templates.length).toBe(1)
73-
const [template] = templates
74+
const template = getOk(templates[0]!)
7475
expectTemplate(
75-
template!,
76+
template,
7677
'[EDITABLE]This is a cloze deletion for [ ... ] .[/EDITABLE]',
7778
'[EDITABLE]This is a cloze deletion for [ Text ] .[/EDITABLE](Extra)',
7879
)
@@ -87,9 +88,9 @@ test('renderTemplate works with plugin that requires `.bind(this)` because it in
8788
const c = await registerPluginServices([plugin])
8889
const templates = c.renderTemplate(clozeWithRequiredEdit)
8990
expect(templates.length).toBe(1)
90-
const [template] = templates
91+
const template = getOk(templates[0]!)
9192
expectTemplate(
92-
template!,
93+
template,
9394
'[EDITABLE]THIS IS A CLOZE DELETION FOR [ ... ] .[/EDITABLE]',
9495
'[EDITABLE]THIS IS A CLOZE DELETION FOR [ TEXT ] .[/EDITABLE](EXTRA)',
9596
)
@@ -104,9 +105,9 @@ test('[EDITABLE] is missing since no `bind(this)`', async () => {
104105
const c = await registerPluginServices([plugin])
105106
const templates = c.renderTemplate(clozeWithRequiredEdit)
106107
expect(templates.length).toBe(1)
107-
const [template] = templates
108+
const template = getOk(templates[0]!)
108109
expectTemplate(
109-
template!,
110+
template,
110111
'THIS IS A CLOZE DELETION FOR [ ... ] .',
111112
'THIS IS A CLOZE DELETION FOR [ TEXT ] .(EXTRA)',
112113
)

shared-dom/src/cardHtml.plugin.testinput.ts

+11-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,17 @@ function renderTemplate(
99
): typeof defaultRenderContainer.renderTemplate {
1010
return function (template) {
1111
const original = c.renderTemplate.bind(this)(template)
12-
return original.map((x) =>
13-
x !== null ? ([x[0].toUpperCase(), x[1].toUpperCase()] as const) : null,
14-
)
12+
return original.map((r) => {
13+
if (r.tag === 'Error') return r
14+
return {
15+
tag: 'Ok',
16+
ok:
17+
r.ok !== null
18+
? ([r.ok[0].toUpperCase(), r.ok[1].toUpperCase()] as const)
19+
: null,
20+
warnings: r.warnings,
21+
}
22+
})
1523
}
1624
}
1725

shared-dom/src/cardHtml.test.ts

+48-21
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,21 @@
11
import { defaultRenderContainer } from './renderContainer'
22
import { describe, expect, test } from 'vitest'
3-
import { type TemplateId, type Ord, type Template, type Note } from 'shared'
3+
import {
4+
type TemplateId,
5+
type Ord,
6+
type Template,
7+
type Note,
8+
type Card,
9+
} from 'shared'
410
import { throwExp } from 'shared'
5-
import { noteOrds, strip, toSampleCard, toSampleNote } from './cardHtml'
11+
import {
12+
type HtmlResult,
13+
noteOrds,
14+
strip,
15+
toSampleCard,
16+
toSampleNote,
17+
getOk as getOkSafe,
18+
} from './cardHtml'
619

720
function buildTemplate(
821
fieldValues: Array<readonly [string, string]>,
@@ -45,6 +58,10 @@ function buildTemplate(
4558
} satisfies Template
4659
}
4760

61+
export function getOk(result: HtmlResult) {
62+
return getOkSafe(result) ?? throwExp('ya goofed')
63+
}
64+
4865
function testBody(
4966
fieldValues: Array<readonly [string, string]>,
5067
frontTemplate: string,
@@ -55,12 +72,12 @@ function testBody(
5572
expectedBack: string,
5673
): void {
5774
const template = buildTemplate(fieldValues, frontTemplate, backTemplate, type)
58-
const [front, back] =
59-
defaultRenderContainer.body(
60-
toSampleCard(ord as Ord),
61-
toSampleNote(new Map(fieldValues)),
62-
template,
63-
) ?? throwExp('should never happen')
75+
const r = defaultRenderContainer.body(
76+
toSampleCard(ord as Ord),
77+
toSampleNote(new Map(fieldValues)),
78+
template,
79+
)
80+
const [front, back] = getOk(r)
6481
expect(front).toBe(expectedFront)
6582
expect(back).toBe(expectedBack)
6683
}
@@ -75,12 +92,13 @@ function testStrippedBody(
7592
expectedBack: string,
7693
): void {
7794
const template = buildTemplate(fieldValues, frontTemplate, backTemplate, type)
78-
const [front, back] =
95+
const [front, back] = getOk(
7996
defaultRenderContainer.body(
8097
toSampleCard(ord as Ord),
8198
toSampleNote(new Map(fieldValues)),
8299
template,
83-
) ?? throwExp('should never happen')
100+
),
101+
)
84102
expectStrippedToBe(front, expectedFront)
85103
expectStrippedToBe(back, expectedBack)
86104
}
@@ -583,12 +601,12 @@ test('CardHtml renders multiple cloze templates properly 4 with hint', () => {
583601
})
584602

585603
function expectTemplate(
586-
template: readonly [string, string] | null,
604+
template: HtmlResult,
587605
expectedFront: string,
588606
expectedBack: string,
589607
): void {
590608
expect(template).not.toBeNull()
591-
const [front, back] = template!
609+
const [front, back] = getOk(template)
592610
expectStrippedToBe(front, expectedFront)
593611
expectStrippedToBe(back, expectedBack)
594612
}
@@ -728,6 +746,15 @@ function toTestNote(
728746
}
729747
}
730748

749+
function toBody(
750+
card: Card,
751+
note: Note,
752+
template: Template,
753+
short: boolean = false,
754+
) {
755+
return getOk(defaultRenderContainer.body(card, note, template, short))
756+
}
757+
731758
describe('standardTemplate tags', () => {
732759
const fieldValues = [
733760
['Back', 'Ottawa'],
@@ -736,7 +763,7 @@ describe('standardTemplate tags', () => {
736763

737764
test('CardHtml generates proper basic card template with no tags', () => {
738765
const [front, back] =
739-
defaultRenderContainer.body(
766+
toBody(
740767
toSampleCard(0 as Ord),
741768
toTestNote(new Map(fieldValues), { tags: new Set() }),
742769
buildTemplate(
@@ -756,7 +783,7 @@ describe('standardTemplate tags', () => {
756783

757784
test('CardHtml generates proper basic card template with 1 tag', () => {
758785
const [front, back] =
759-
defaultRenderContainer.body(
786+
toBody(
760787
toSampleCard(0 as Ord),
761788
toTestNote(new Map(fieldValues), { tags: new Set(['Geography']) }),
762789
buildTemplate(
@@ -776,7 +803,7 @@ describe('standardTemplate tags', () => {
776803

777804
test('CardHtml generates proper basic card template with 2 tags', () => {
778805
const [front, back] =
779-
defaultRenderContainer.body(
806+
toBody(
780807
toSampleCard(0 as Ord),
781808
toTestNote(new Map(fieldValues), {
782809
tags: new Set(['Geography', 'Capital']),
@@ -798,7 +825,7 @@ describe('standardTemplate tags', () => {
798825

799826
test('CardHtml generates proper basic card template with no conditional tags', () => {
800827
const [front, back] =
801-
defaultRenderContainer.body(
828+
toBody(
802829
toSampleCard(0 as Ord),
803830
toTestNote(new Map(fieldValues), { tags: new Set() }),
804831
buildTemplate(
@@ -818,7 +845,7 @@ describe('standardTemplate tags', () => {
818845

819846
test('CardHtml generates proper basic card template with 1 conditional tag', () => {
820847
const [front, back] =
821-
defaultRenderContainer.body(
848+
toBody(
822849
toSampleCard(0 as Ord),
823850
toTestNote(new Map(fieldValues), { tags: new Set(['Geography']) }),
824851
buildTemplate(
@@ -838,7 +865,7 @@ describe('standardTemplate tags', () => {
838865

839866
test('CardHtml generates proper basic card template with 2 conditional tags', () => {
840867
const [front, back] =
841-
defaultRenderContainer.body(
868+
toBody(
842869
toSampleCard(0 as Ord),
843870
toTestNote(new Map(fieldValues), {
844871
tags: new Set(['Geography', 'Capital']),
@@ -860,7 +887,7 @@ describe('standardTemplate tags', () => {
860887

861888
test('CardHtml generates proper basic card template with no antiConditional tags', () => {
862889
const [front, back] =
863-
defaultRenderContainer.body(
890+
toBody(
864891
toSampleCard(0 as Ord),
865892
toTestNote(new Map(fieldValues), { tags: new Set() }),
866893
buildTemplate(
@@ -880,7 +907,7 @@ describe('standardTemplate tags', () => {
880907

881908
test('CardHtml generates proper basic card template with 1 antiConditional tag', () => {
882909
const [front, back] =
883-
defaultRenderContainer.body(
910+
toBody(
884911
toSampleCard(0 as Ord),
885912
toTestNote(new Map(fieldValues), { tags: new Set(['Geography']) }),
886913
buildTemplate(
@@ -900,7 +927,7 @@ describe('standardTemplate tags', () => {
900927

901928
test('CardHtml generates proper basic card template with 2 antiConditional tags', () => {
902929
const [front, back] =
903-
defaultRenderContainer.body(
930+
toBody(
904931
toSampleCard(0 as Ord),
905932
toTestNote(new Map(fieldValues), {
906933
tags: new Set(['Geography', 'Capital']),

0 commit comments

Comments
 (0)