@webority/mobile-chat 0.111.0 → 0.113.0
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/README.md +5 -4
- package/lib/commonjs/components/ChatMarkdown.js +1 -1
- package/lib/commonjs/components/ChatMessage.js +1 -1
- package/lib/module/components/ChatMarkdown.js +1 -1
- package/lib/module/components/ChatMessage.js +1 -1
- package/lib/typescript/commonjs/components/ChatMarkdown.d.ts +1 -7
- package/lib/typescript/module/components/ChatMarkdown.d.ts +1 -7
- package/package.json +9 -6
- package/lib/commonjs/markdownParse.js +0 -1
- package/lib/module/markdownParse.js +0 -1
- package/lib/typescript/commonjs/markdownParse.d.ts +0 -59
- package/lib/typescript/module/markdownParse.d.ts +0 -59
package/README.md
CHANGED
|
@@ -130,10 +130,11 @@ package's, so a product passes one label set to both; `composerHint` is not show
|
|
|
130
130
|
`keyboardAware={false}` to both inside a container that already does, and `keyboardOffset` (the
|
|
131
131
|
tab bar height) above a tab bar. The composer's return key adds a new line; only the send button
|
|
132
132
|
sends.
|
|
133
|
-
- **`ChatMarkdown`**: renders a reply
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
- **`ChatMarkdown`**: renders a reply through mobile-ui's `Markdown`, the one Markdown renderer
|
|
134
|
+
the phone uses, so the reply draws the same subset of Markdown as every other surface: paragraphs,
|
|
135
|
+
bold, italics, inline code, bullet and numbered lists, simple tables (scrolling sideways),
|
|
136
|
+
headings, code blocks and rules. A link shows only when its href has the form `scheme:kind/id`
|
|
137
|
+
and `resolveLink(href)` returns something; pressing it calls `onLinkPress(target)`. A web address
|
|
137
138
|
never opens, and shows its label as plain text.
|
|
138
139
|
- **`ReplyRating`**: Helpful and Not helpful under a stored reply; Not helpful then offers an
|
|
139
140
|
optional note (`noteMaxLength`, default 1000).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMarkdown=ChatMarkdown;var _mobileUi=require("@webority/mobile-ui"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMarkdown=ChatMarkdown;var _mobileUi=require("@webority/mobile-ui"),_jsxRuntime=require("react/jsx-runtime");function ChatMarkdown({text:e,resolveLink:r,onLinkPress:t,testID:i}){return(0,_jsxRuntime.jsx)(_mobileUi.Markdown,{links:"app",headings:"text",resolveLink:r,onAppLinkPress:t,testID:i,children:e})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMessage=void 0;var _mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_labels=require("../labels.js"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.ChatMessage=void 0;var _markdownCore=require("@webority/markdown-core"),_mobileUi=require("@webority/mobile-ui"),_react=require("react"),_reactNative=require("react-native"),_labels=require("../labels.js"),_ActionCard=require("./ActionCard.js"),_ChatMarkdown=require("./ChatMarkdown.js"),_ReplyRating=require("./ReplyRating.js"),_jsxRuntime=require("react/jsx-runtime");function ChatMessageView({turn:e,onRate:t,resolveLink:i,onLinkPress:s,confirmAction:r,onViewTicket:a,renderReply:n,labels:o,testID:l="chat-message"}){const m=(0,_labels.mergeLabels)(o),u=(0,_mobileUi.useTheme)(),c=e.streaming&&!e.answer,_=(0,_react.useMemo)(()=>e.streaming?e.answer:(0,_markdownCore.markdownToPlainText)(e.answer),[e.streaming,e.answer]),g=(0,_react.useMemo)(()=>({you:m.you}),[m.you]);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{gap:u.space.sm},testID:l,children:[""!==e.question&&(0,_jsxRuntime.jsx)(_mobileUi.MessageBubble,{side:"mine",text:e.question,labels:g,testID:`${l}-question`}),c?(0,_jsxRuntime.jsx)(_mobileUi.TypingIndicator,{label:m.thinking,testID:`${l}-thinking`}):null,""!==e.answer?(0,_jsxRuntime.jsx)(_mobileUi.MessageBubble,{side:"theirs",author:m.assistant,text:_,streaming:e.streaming,testID:`${l}-answer`,children:n?n(e,{streaming:e.streaming}):(0,_jsxRuntime.jsx)(_ChatMarkdown.ChatMarkdown,{text:e.answer,resolveLink:i,onLinkPress:s})}):null,e.error&&(0,_jsxRuntime.jsx)(_mobileUi.Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:e.error.message}),r&&!e.streaming&&e.actions.map(e=>(0,_jsxRuntime.jsx)(_ActionCard.ActionCard,{action:e,confirmAction:r,onViewTicket:a,labels:o},e.token)),t&&e.messageId&&!e.streaming&&(0,_jsxRuntime.jsx)(_ReplyRating.ReplyRating,{rating:e.rating,onRate:(i,s)=>t(e.id,i,s),labels:o})]})}const ChatMessage=exports.ChatMessage=(0,_react.memo)(ChatMessageView);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{
|
|
1
|
+
"use strict";import{Markdown}from"@webority/mobile-ui";import{jsx as _jsx}from"react/jsx-runtime";export function ChatMarkdown({text:e,resolveLink:r,onLinkPress:t,testID:s}){return _jsx(Markdown,{links:"app",headings:"text",resolveLink:r,onAppLinkPress:t,testID:s,children:e})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{MessageBubble,Text,TypingIndicator,useTheme}from"@webority/mobile-ui";import{memo,useMemo}from"react";import{View}from"react-native";import{mergeLabels}from"../labels.js";import{
|
|
1
|
+
"use strict";import{markdownToPlainText}from"@webority/markdown-core";import{MessageBubble,Text,TypingIndicator,useTheme}from"@webority/mobile-ui";import{memo,useMemo}from"react";import{View}from"react-native";import{mergeLabels}from"../labels.js";import{ActionCard}from"./ActionCard.js";import{ChatMarkdown}from"./ChatMarkdown.js";import{ReplyRating}from"./ReplyRating.js";import{jsx as _jsx,jsxs as _jsxs}from"react/jsx-runtime";function ChatMessageView({turn:e,onRate:s,resolveLink:t,onLinkPress:r,confirmAction:i,onViewTicket:a,renderReply:n,labels:o,testID:m="chat-message"}){const l=mergeLabels(o),g=useTheme(),c=e.streaming&&!e.answer,u=useMemo(()=>e.streaming?e.answer:markdownToPlainText(e.answer),[e.streaming,e.answer]),d=useMemo(()=>({you:l.you}),[l.you]);return _jsxs(View,{style:{gap:g.space.sm},testID:m,children:[""!==e.question&&_jsx(MessageBubble,{side:"mine",text:e.question,labels:d,testID:`${m}-question`}),c?_jsx(TypingIndicator,{label:l.thinking,testID:`${m}-thinking`}):null,""!==e.answer?_jsx(MessageBubble,{side:"theirs",author:l.assistant,text:u,streaming:e.streaming,testID:`${m}-answer`,children:n?n(e,{streaming:e.streaming}):_jsx(ChatMarkdown,{text:e.answer,resolveLink:t,onLinkPress:r})}):null,e.error&&_jsx(Text,{variant:"bodySmall",color:"danger",accessibilityLiveRegion:"polite",children:e.error.message}),i&&!e.streaming&&e.actions.map(e=>_jsx(ActionCard,{action:e,confirmAction:i,onViewTicket:a,labels:o},e.token)),s&&e.messageId&&!e.streaming&&_jsx(ReplyRating,{rating:e.rating,onRate:(t,r)=>s(e.id,t,r),labels:o})]})}export const ChatMessage=memo(ChatMessageView);
|
|
@@ -12,12 +12,6 @@ export interface ChatMarkdownProps<T = string> {
|
|
|
12
12
|
onLinkPress?: (target: T) => void;
|
|
13
13
|
testID?: string;
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Renders a reply from a small, safe subset of Markdown: paragraphs, bold, italics, inline code,
|
|
17
|
-
* bullet and numbered lists, simple tables (scrolling sideways), headings (as bold lines), code
|
|
18
|
-
* blocks and rules. It never opens a web address: a link shows only when its href has the form
|
|
19
|
-
* `scheme:kind/id` and `resolveLink` maps it. Text still arriving updates the last block in place,
|
|
20
|
-
* and an unclosed `**` shows as typed until its partner arrives.
|
|
21
|
-
*/
|
|
15
|
+
/** A reply never opens a web address, and its headings draw as bold lines, not large type. */
|
|
22
16
|
export declare function ChatMarkdown<T = string>({ text, resolveLink, onLinkPress, testID }: ChatMarkdownProps<T>): React.ReactElement;
|
|
23
17
|
//# sourceMappingURL=ChatMarkdown.d.ts.map
|
|
@@ -12,12 +12,6 @@ export interface ChatMarkdownProps<T = string> {
|
|
|
12
12
|
onLinkPress?: (target: T) => void;
|
|
13
13
|
testID?: string;
|
|
14
14
|
}
|
|
15
|
-
/**
|
|
16
|
-
* Renders a reply from a small, safe subset of Markdown: paragraphs, bold, italics, inline code,
|
|
17
|
-
* bullet and numbered lists, simple tables (scrolling sideways), headings (as bold lines), code
|
|
18
|
-
* blocks and rules. It never opens a web address: a link shows only when its href has the form
|
|
19
|
-
* `scheme:kind/id` and `resolveLink` maps it. Text still arriving updates the last block in place,
|
|
20
|
-
* and an unclosed `**` shows as typed until its partner arrives.
|
|
21
|
-
*/
|
|
15
|
+
/** A reply never opens a web address, and its headings draw as bold lines, not large type. */
|
|
22
16
|
export declare function ChatMarkdown<T = string>({ text, resolveLink, onLinkPress, testID }: ChatMarkdownProps<T>): React.ReactElement;
|
|
23
17
|
//# sourceMappingURL=ChatMarkdown.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webority/mobile-chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.113.0",
|
|
4
4
|
"description": "AI assistant chat for Webority React Native apps: a streaming chat client, a store-agnostic chat hook, and the chat screen, thread, composer, past chats, reply rating and support action cards, built on @webority/mobile-ui.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react-native",
|
|
@@ -41,13 +41,16 @@
|
|
|
41
41
|
"!**/*.spec.*",
|
|
42
42
|
"!**/*.map"
|
|
43
43
|
],
|
|
44
|
+
"dependencies": {
|
|
45
|
+
"@webority/markdown-core": "0.113.0"
|
|
46
|
+
},
|
|
44
47
|
"peerDependencies": {
|
|
45
48
|
"react": "^19.1.0",
|
|
46
49
|
"react-native": ">=0.81.0",
|
|
47
50
|
"react-native-keyboard-controller": ">=1.21.9",
|
|
48
51
|
"react-native-safe-area-context": ">=5.4.0",
|
|
49
|
-
"@webority/mobile-core": "0.
|
|
50
|
-
"@webority/mobile-ui": "0.
|
|
52
|
+
"@webority/mobile-core": "0.113.0",
|
|
53
|
+
"@webority/mobile-ui": "0.113.0"
|
|
51
54
|
},
|
|
52
55
|
"peerDependenciesMeta": {},
|
|
53
56
|
"publishConfig": {
|
|
@@ -93,9 +96,9 @@
|
|
|
93
96
|
"react-test-renderer": "19.2.8",
|
|
94
97
|
"rimraf": "6.1.3",
|
|
95
98
|
"typescript": "5.9.3",
|
|
96
|
-
"@webority/mobile-
|
|
97
|
-
"@webority/mobile-
|
|
98
|
-
"@webority/mobile-
|
|
99
|
+
"@webority/mobile-dev": "0.0.0",
|
|
100
|
+
"@webority/mobile-core": "0.113.0",
|
|
101
|
+
"@webority/mobile-ui": "0.113.0"
|
|
99
102
|
},
|
|
100
103
|
"scripts": {
|
|
101
104
|
"build": "bob build && node ../mobile-dev/scripts/minify-lib.mjs",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),exports.parseInline=exports.parseBlocks=exports.linkTarget=void 0;const LINK_HREF=/^[a-z][a-z0-9+.-]*:[a-z0-9_-]+\/[a-z0-9_.~-]+$/i,FENCE=/^\s*```/,BULLET=/^\s*[-*+]\s+(.*)$/,ORDERED=/^\s*(\d{1,9})[.)]\s+(.*)$/,HEADING=/^\s{0,3}#{1,6}\s+(.*?)\s*#*\s*$/,RULE=/^\s*([-*_])(\s*\1){2,}\s*$/,TABLE_SEPARATOR=/^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$/,isTableRow=e=>e.includes("|"),tableCells=e=>{let t=e.trim();return t.startsWith("|")&&(t=t.slice(1)),t.endsWith("|")&&(t=t.slice(0,-1)),t.split("|").map(e=>e.trim())},startsTable=(e,t)=>isTableRow(e[t])&&t+1<e.length&&TABLE_SEPARATOR.test(e[t+1]),startsBlock=(e,t)=>{const s=e[t];return FENCE.test(s)||BULLET.test(s)||ORDERED.test(s)||HEADING.test(s)||RULE.test(s)||startsTable(e,t)},parseBlocks=e=>{const t=String(e??"").replace(/\r\n?/g,"\n").split("\n"),s=[];let n=0;for(;n<t.length;){const e=t[n];if(!e.trim()){n+=1;continue}if(FENCE.test(e)){const e=[];for(n+=1;n<t.length&&!FENCE.test(t[n]);)e.push(t[n]),n+=1;n+=1,s.push({type:"code",text:e.join("\n")});continue}if(startsTable(t,n)){const i=tableCells(e),r=[];for(n+=2;n<t.length&&t[n].trim()&&isTableRow(t[n]);)r.push(tableCells(t[n])),n+=1;s.push({type:"table",header:i,rows:r});continue}if(RULE.test(e)){s.push({type:"rule"}),n+=1;continue}const i=HEADING.exec(e);if(i){s.push({type:"heading",text:i[1]}),n+=1;continue}const r=ORDERED.exec(e);if(r||BULLET.test(e)){const e=Boolean(r),i=e?ORDERED:BULLET,l=[];for(;n<t.length&&t[n].trim();){const s=i.exec(t[n]);if(s)l.push(e?s[2]:s[1]);else{if(startsBlock(t,n))break;l[l.length-1]+=` ${t[n].trim()}`}n+=1}s.push({type:"list",ordered:e,start:r?Number(r[1]):1,items:l});continue}const l=[e];for(n+=1;n<t.length&&t[n].trim()&&!startsBlock(t,n);)l.push(t[n]),n+=1;s.push({type:"paragraph",lines:l})}return s.map((e,t)=>({...e,key:t}))};exports.parseBlocks=parseBlocks;const isWordChar=e=>Boolean(e)&&/[\p{L}\p{N}]/u.test(e??""),findClose=(e,t,s)=>{let n=e.indexOf(s,t);for(;-1!==n;){const i=e.slice(t,n),r=1===s.length&&(e[n+1]===s||e[n-1]===s),l="_"===s[0]&&isWordChar(e[n+s.length]);if(i.trim()&&!/^\s/.test(i)&&!/\s$/.test(i)&&!r&&!l)return n;n=e.indexOf(s,n+1)}return-1},parseInline=e=>{const t=[];let s="";const flush=()=>{s&&t.push({type:"text",text:s}),s=""};let n=0;for(;n<e.length;){const i=e[n];if("`"===i){const s=e.indexOf("`",n+1);if(s>n+1){flush(),t.push({type:"code",text:e.slice(n+1,s)}),n=s+1;continue}}if(("*"===i||"_"===i)&&e[n+1]===i){const r=i+i,l=findClose(e,n+2,r);if(-1!==l&&("_"!==i||!isWordChar(e[n-1]))){flush(),t.push({type:"strong",children:parseInline(e.slice(n+2,l))}),n=l+2;continue}s+=r,n+=2;continue}if("*"===i||"_"===i){const s=findClose(e,n+1,i);if(-1!==s&&("_"!==i||!isWordChar(e[n-1]))){flush(),t.push({type:"em",children:parseInline(e.slice(n+1,s))}),n=s+1;continue}}if("["===i){const s=/^\[([^\]\n]+)\]\(([^)\s]+)\)/.exec(e.slice(n));if(s){flush(),t.push({type:"link",href:s[2],children:parseInline(s[1])}),n+=s[0].length;continue}}s+=i,n+=1}return flush(),t.map((e,t)=>({...e,key:t}))};exports.parseInline=parseInline;const linkTarget=(e,t)=>t&&LINK_HREF.test(e)?t(e)??null:null;exports.linkTarget=linkTarget;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const LINK_HREF=/^[a-z][a-z0-9+.-]*:[a-z0-9_-]+\/[a-z0-9_.~-]+$/i,FENCE=/^\s*```/,BULLET=/^\s*[-*+]\s+(.*)$/,ORDERED=/^\s*(\d{1,9})[.)]\s+(.*)$/,HEADING=/^\s{0,3}#{1,6}\s+(.*?)\s*#*\s*$/,RULE=/^\s*([-*_])(\s*\1){2,}\s*$/,TABLE_SEPARATOR=/^\s*\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)*\|?\s*$/,isTableRow=t=>t.includes("|"),tableCells=t=>{let e=t.trim();return e.startsWith("|")&&(e=e.slice(1)),e.endsWith("|")&&(e=e.slice(0,-1)),e.split("|").map(t=>t.trim())},startsTable=(t,e)=>isTableRow(t[e])&&e+1<t.length&&TABLE_SEPARATOR.test(t[e+1]),startsBlock=(t,e)=>{const s=t[e];return FENCE.test(s)||BULLET.test(s)||ORDERED.test(s)||HEADING.test(s)||RULE.test(s)||startsTable(t,e)};export const parseBlocks=t=>{const e=String(t??"").replace(/\r\n?/g,"\n").split("\n"),s=[];let n=0;for(;n<e.length;){const t=e[n];if(!t.trim()){n+=1;continue}if(FENCE.test(t)){const t=[];for(n+=1;n<e.length&&!FENCE.test(e[n]);)t.push(e[n]),n+=1;n+=1,s.push({type:"code",text:t.join("\n")});continue}if(startsTable(e,n)){const i=tableCells(t),r=[];for(n+=2;n<e.length&&e[n].trim()&&isTableRow(e[n]);)r.push(tableCells(e[n])),n+=1;s.push({type:"table",header:i,rows:r});continue}if(RULE.test(t)){s.push({type:"rule"}),n+=1;continue}const i=HEADING.exec(t);if(i){s.push({type:"heading",text:i[1]}),n+=1;continue}const r=ORDERED.exec(t);if(r||BULLET.test(t)){const t=Boolean(r),i=t?ORDERED:BULLET,l=[];for(;n<e.length&&e[n].trim();){const s=i.exec(e[n]);if(s)l.push(t?s[2]:s[1]);else{if(startsBlock(e,n))break;l[l.length-1]+=` ${e[n].trim()}`}n+=1}s.push({type:"list",ordered:t,start:r?Number(r[1]):1,items:l});continue}const l=[t];for(n+=1;n<e.length&&e[n].trim()&&!startsBlock(e,n);)l.push(e[n]),n+=1;s.push({type:"paragraph",lines:l})}return s.map((t,e)=>({...t,key:e}))};const isWordChar=t=>Boolean(t)&&/[\p{L}\p{N}]/u.test(t??""),findClose=(t,e,s)=>{let n=t.indexOf(s,e);for(;-1!==n;){const i=t.slice(e,n),r=1===s.length&&(t[n+1]===s||t[n-1]===s),l="_"===s[0]&&isWordChar(t[n+s.length]);if(i.trim()&&!/^\s/.test(i)&&!/\s$/.test(i)&&!r&&!l)return n;n=t.indexOf(s,n+1)}return-1};export const parseInline=t=>{const e=[];let s="";const flush=()=>{s&&e.push({type:"text",text:s}),s=""};let n=0;for(;n<t.length;){const i=t[n];if("`"===i){const s=t.indexOf("`",n+1);if(s>n+1){flush(),e.push({type:"code",text:t.slice(n+1,s)}),n=s+1;continue}}if(("*"===i||"_"===i)&&t[n+1]===i){const r=i+i,l=findClose(t,n+2,r);if(-1!==l&&("_"!==i||!isWordChar(t[n-1]))){flush(),e.push({type:"strong",children:parseInline(t.slice(n+2,l))}),n=l+2;continue}s+=r,n+=2;continue}if("*"===i||"_"===i){const s=findClose(t,n+1,i);if(-1!==s&&("_"!==i||!isWordChar(t[n-1]))){flush(),e.push({type:"em",children:parseInline(t.slice(n+1,s))}),n=s+1;continue}}if("["===i){const s=/^\[([^\]\n]+)\]\(([^)\s]+)\)/.exec(t.slice(n));if(s){flush(),e.push({type:"link",href:s[2],children:parseInline(s[1])}),n+=s[0].length;continue}}s+=i,n+=1}return flush(),e.map((t,e)=>({...t,key:e}))};export const linkTarget=(t,e)=>e&&LINK_HREF.test(t)?e(t)??null:null;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
type BlockShape = {
|
|
2
|
-
type: "paragraph";
|
|
3
|
-
lines: string[];
|
|
4
|
-
} | {
|
|
5
|
-
type: "heading";
|
|
6
|
-
text: string;
|
|
7
|
-
} | {
|
|
8
|
-
type: "list";
|
|
9
|
-
ordered: boolean;
|
|
10
|
-
start: number;
|
|
11
|
-
items: string[];
|
|
12
|
-
} | {
|
|
13
|
-
type: "table";
|
|
14
|
-
header: string[];
|
|
15
|
-
rows: string[][];
|
|
16
|
-
} | {
|
|
17
|
-
type: "code";
|
|
18
|
-
text: string;
|
|
19
|
-
} | {
|
|
20
|
-
type: "rule";
|
|
21
|
-
};
|
|
22
|
-
export type MarkdownBlock = BlockShape & {
|
|
23
|
-
key: number;
|
|
24
|
-
};
|
|
25
|
-
type InlineShape = {
|
|
26
|
-
type: "text";
|
|
27
|
-
text: string;
|
|
28
|
-
} | {
|
|
29
|
-
type: "code";
|
|
30
|
-
text: string;
|
|
31
|
-
} | {
|
|
32
|
-
type: "strong" | "em";
|
|
33
|
-
children: InlineToken[];
|
|
34
|
-
} | {
|
|
35
|
-
type: "link";
|
|
36
|
-
href: string;
|
|
37
|
-
children: InlineToken[];
|
|
38
|
-
};
|
|
39
|
-
export type InlineToken = InlineShape & {
|
|
40
|
-
key: number;
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Splits reply text into blocks: paragraphs, headings, bullet and numbered lists, simple tables,
|
|
44
|
-
* code blocks and rules. Each block's `key` is its position, so text arriving at the end of a
|
|
45
|
-
* streaming reply updates the last block in place and never remounts the ones before it.
|
|
46
|
-
*/
|
|
47
|
-
export declare const parseBlocks: (text: string | null | undefined) => MarkdownBlock[];
|
|
48
|
-
/**
|
|
49
|
-
* Reads bold (`**` or `__`), italics (`*` or `_`), inline code and `[label](href)` links. A marker
|
|
50
|
-
* with no partner yet (a reply still streaming) shows as the characters typed.
|
|
51
|
-
*/
|
|
52
|
-
export declare const parseInline: (text: string) => InlineToken[];
|
|
53
|
-
/**
|
|
54
|
-
* What a reply link opens, or null when it may not open anything. Only `scheme:kind/id` hrefs
|
|
55
|
-
* reach `resolveLink`; a web address never does, so a reply cannot send the person off the app.
|
|
56
|
-
*/
|
|
57
|
-
export declare const linkTarget: <T>(href: string, resolveLink: ((href: string) => T | null | undefined) | undefined) => T | null;
|
|
58
|
-
export {};
|
|
59
|
-
//# sourceMappingURL=markdownParse.d.ts.map
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
type BlockShape = {
|
|
2
|
-
type: "paragraph";
|
|
3
|
-
lines: string[];
|
|
4
|
-
} | {
|
|
5
|
-
type: "heading";
|
|
6
|
-
text: string;
|
|
7
|
-
} | {
|
|
8
|
-
type: "list";
|
|
9
|
-
ordered: boolean;
|
|
10
|
-
start: number;
|
|
11
|
-
items: string[];
|
|
12
|
-
} | {
|
|
13
|
-
type: "table";
|
|
14
|
-
header: string[];
|
|
15
|
-
rows: string[][];
|
|
16
|
-
} | {
|
|
17
|
-
type: "code";
|
|
18
|
-
text: string;
|
|
19
|
-
} | {
|
|
20
|
-
type: "rule";
|
|
21
|
-
};
|
|
22
|
-
export type MarkdownBlock = BlockShape & {
|
|
23
|
-
key: number;
|
|
24
|
-
};
|
|
25
|
-
type InlineShape = {
|
|
26
|
-
type: "text";
|
|
27
|
-
text: string;
|
|
28
|
-
} | {
|
|
29
|
-
type: "code";
|
|
30
|
-
text: string;
|
|
31
|
-
} | {
|
|
32
|
-
type: "strong" | "em";
|
|
33
|
-
children: InlineToken[];
|
|
34
|
-
} | {
|
|
35
|
-
type: "link";
|
|
36
|
-
href: string;
|
|
37
|
-
children: InlineToken[];
|
|
38
|
-
};
|
|
39
|
-
export type InlineToken = InlineShape & {
|
|
40
|
-
key: number;
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Splits reply text into blocks: paragraphs, headings, bullet and numbered lists, simple tables,
|
|
44
|
-
* code blocks and rules. Each block's `key` is its position, so text arriving at the end of a
|
|
45
|
-
* streaming reply updates the last block in place and never remounts the ones before it.
|
|
46
|
-
*/
|
|
47
|
-
export declare const parseBlocks: (text: string | null | undefined) => MarkdownBlock[];
|
|
48
|
-
/**
|
|
49
|
-
* Reads bold (`**` or `__`), italics (`*` or `_`), inline code and `[label](href)` links. A marker
|
|
50
|
-
* with no partner yet (a reply still streaming) shows as the characters typed.
|
|
51
|
-
*/
|
|
52
|
-
export declare const parseInline: (text: string) => InlineToken[];
|
|
53
|
-
/**
|
|
54
|
-
* What a reply link opens, or null when it may not open anything. Only `scheme:kind/id` hrefs
|
|
55
|
-
* reach `resolveLink`; a web address never does, so a reply cannot send the person off the app.
|
|
56
|
-
*/
|
|
57
|
-
export declare const linkTarget: <T>(href: string, resolveLink: ((href: string) => T | null | undefined) | undefined) => T | null;
|
|
58
|
-
export {};
|
|
59
|
-
//# sourceMappingURL=markdownParse.d.ts.map
|