shelving 1.86.0 → 1.86.2
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/api/Resource.d.ts +2 -2
- package/constraint/Constraints.js +7 -6
- package/constraint/FilterConstraint.d.ts +4 -4
- package/constraint/FilterConstraint.js +17 -17
- package/constraint/QueryConstraints.d.ts +1 -1
- package/constraint/QueryConstraints.js +8 -8
- package/constraint/SortConstraint.d.ts +4 -4
- package/constraint/SortConstraint.js +3 -3
- package/db/Change.d.ts +4 -4
- package/db/Item.d.ts +4 -4
- package/error/ThroughError.js +1 -1
- package/markup/index.d.ts +1 -0
- package/markup/index.js +1 -0
- package/markup/options.d.ts +2 -2
- package/markup/regexp.d.ts +2 -2
- package/markup/render.js +19 -20
- package/markup/rule.d.ts +80 -0
- package/markup/rule.js +63 -0
- package/markup/rules.d.ts +17 -67
- package/markup/rules.js +88 -160
- package/package.json +17 -17
- package/react/useItem.js +10 -10
- package/react/useQuery.js +29 -29
- package/schema/AllowSchema.d.ts +4 -4
- package/schema/AllowSchema.js +3 -3
- package/schema/ArraySchema.d.ts +1 -1
- package/schema/BooleanSchema.d.ts +1 -1
- package/schema/DataSchema.d.ts +2 -2
- package/schema/DateSchema.d.ts +1 -1
- package/schema/DictionarySchema.d.ts +1 -1
- package/schema/LinkSchema.d.ts +1 -1
- package/schema/NumberSchema.d.ts +1 -1
- package/schema/NumberSchema.js +4 -4
- package/schema/Schema.d.ts +1 -1
- package/schema/StringSchema.d.ts +3 -3
- package/schema/ThroughSchema.d.ts +1 -1
- package/schema/TimeSchema.d.ts +1 -1
- package/state/State.d.ts +1 -1
- package/state/State.js +6 -6
- package/test/basics.d.ts +2 -2
- package/test/index.d.ts +1 -1
- package/test/people.d.ts +2 -2
- package/update/ArrayUpdate.d.ts +2 -1
- package/update/ArrayUpdate.js +9 -8
- package/update/DataUpdate.d.ts +1 -1
- package/update/DataUpdate.js +7 -6
- package/update/DictionaryUpdate.d.ts +1 -1
- package/update/DictionaryUpdate.js +8 -7
- package/util/array.d.ts +4 -4
- package/util/async.js +8 -8
- package/util/class.d.ts +3 -3
- package/util/clone.js +4 -3
- package/util/color.d.ts +2 -2
- package/util/color.js +6 -6
- package/util/data.d.ts +7 -14
- package/util/data.js +1 -19
- package/util/date.d.ts +3 -3
- package/util/debug.d.ts +1 -0
- package/util/debug.js +5 -5
- package/util/dictionary.d.ts +5 -5
- package/util/duration.d.ts +17 -0
- package/util/duration.js +52 -0
- package/util/entry.d.ts +3 -3
- package/util/equal.js +6 -3
- package/util/function.d.ts +8 -8
- package/util/hydrate.d.ts +3 -3
- package/util/hydrate.js +2 -2
- package/util/index.d.ts +1 -0
- package/util/index.js +1 -0
- package/util/iterate.d.ts +1 -1
- package/util/jsx.d.ts +3 -3
- package/util/lazy.d.ts +1 -1
- package/util/map.d.ts +15 -19
- package/util/map.js +11 -13
- package/util/match.d.ts +2 -2
- package/util/merge.d.ts +1 -1
- package/util/null.d.ts +1 -1
- package/util/number.d.ts +4 -2
- package/util/number.js +8 -6
- package/util/object.d.ts +24 -11
- package/util/object.js +30 -4
- package/util/regexp.d.ts +2 -3
- package/util/serialise.js +2 -2
- package/util/set.d.ts +4 -4
- package/util/sort.d.ts +2 -2
- package/util/source.js +2 -2
- package/util/string.d.ts +1 -1
- package/util/string.js +3 -3
- package/util/template.d.ts +2 -2
- package/util/template.js +9 -9
- package/util/time.d.ts +2 -2
- package/util/time.js +3 -3
- package/util/transform.d.ts +5 -5
- package/util/units.d.ts +39 -50
- package/util/units.js +36 -74
- package/util/url.d.ts +2 -2
- package/util/validate.d.ts +5 -5
package/markup/rules.d.ts
CHANGED
|
@@ -1,49 +1,14 @@
|
|
|
1
|
-
import type { Data } from "../util/data.js";
|
|
2
1
|
import type { JSXElement } from "../util/jsx.js";
|
|
3
|
-
import { NamedRegExp
|
|
4
|
-
import { MarkupMatcher } from "./regexp.js";
|
|
2
|
+
import { NamedRegExp } from "../util/regexp.js";
|
|
5
3
|
import type { MarkupOptions } from "./options.js";
|
|
6
|
-
|
|
7
|
-
export interface MarkupRule<T extends Data | undefined = Data | undefined> {
|
|
8
|
-
/**
|
|
9
|
-
* Regular expression or custom matching function.
|
|
10
|
-
*/
|
|
11
|
-
readonly match: (T extends undefined ? RegExp : T extends NamedRegExpData ? NamedRegExp<T> : never) | MarkupMatcher<T>;
|
|
12
|
-
/**
|
|
13
|
-
* Render the JSX element for this rule using the props matched by
|
|
14
|
-
*/
|
|
15
|
-
readonly render: (orops: T, options: MarkupOptions) => JSXElement;
|
|
16
|
-
/**
|
|
17
|
-
* Contexts this rule should be applied in,
|
|
18
|
-
*
|
|
19
|
-
* @example `["block", "inline", "list"]`
|
|
20
|
-
*/
|
|
21
|
-
readonly contexts: string[];
|
|
22
|
-
/**
|
|
23
|
-
* Context that children should be rendered with.
|
|
24
|
-
*
|
|
25
|
-
* @example `"inline"` // Children of the element rendered by this rule will be parsed against markup rules applied in the "inline" context.
|
|
26
|
-
*/
|
|
27
|
-
readonly subcontext?: string;
|
|
28
|
-
/**
|
|
29
|
-
* Priority for this rule (defaults to zero).
|
|
30
|
-
*
|
|
31
|
-
* @example e.g. `<p>` rule is lower priority than other blocks so it matches last and paragraphs can be interrupted by e.g. `<ul>` and `<blockquote>`.
|
|
32
|
-
* @example e.g. `<code>` rule is higher priority than other inlines so e.g. `<strong>` or `<em>` don't match inside a code block.
|
|
33
|
-
*/
|
|
34
|
-
readonly priority?: number;
|
|
35
|
-
}
|
|
36
|
-
/** Any markup rule. */
|
|
37
|
-
export declare type AnyMarkupRule = MarkupRule<any>;
|
|
38
|
-
/** A set of markup rules (as an object or array). */
|
|
39
|
-
export declare type MarkupRules = AnyMarkupRule[];
|
|
4
|
+
import { LinkRegExpMarkupRule, MarkupRules, NamedRegExpMarkupRule, RegExpMarkupRule } from "./rule.js";
|
|
40
5
|
/**
|
|
41
6
|
* Headings are single line only (don't allow multiline).
|
|
42
7
|
* - 1-6 hashes then 1+ spaces, then the title.
|
|
43
8
|
* - Same as Markdown syntax.
|
|
44
9
|
* - Markdown's underline syntax is not supported (for simplification).
|
|
45
10
|
*/
|
|
46
|
-
export declare const HEADING_RULE:
|
|
11
|
+
export declare const HEADING_RULE: NamedRegExpMarkupRule<{
|
|
47
12
|
prefix: string;
|
|
48
13
|
heading: string;
|
|
49
14
|
}>;
|
|
@@ -54,14 +19,14 @@ export declare const HEADING_RULE: MarkupRule<{
|
|
|
54
19
|
* - Character must be the same every time (can't mix)
|
|
55
20
|
* - Might have infinite number of spaces between the characters.
|
|
56
21
|
*/
|
|
57
|
-
export declare const SEPARATOR_RULE:
|
|
58
|
-
export declare const UNORDERED_RULE:
|
|
22
|
+
export declare const SEPARATOR_RULE: RegExpMarkupRule;
|
|
23
|
+
export declare const UNORDERED_RULE: NamedRegExpMarkupRule<{
|
|
59
24
|
list: string;
|
|
60
25
|
}>;
|
|
61
|
-
export declare const ORDERED_RULE:
|
|
26
|
+
export declare const ORDERED_RULE: NamedRegExpMarkupRule<{
|
|
62
27
|
list: string;
|
|
63
28
|
}>;
|
|
64
|
-
export declare const BLOCKQUOTE_RULE:
|
|
29
|
+
export declare const BLOCKQUOTE_RULE: NamedRegExpMarkupRule<{
|
|
65
30
|
quote: string;
|
|
66
31
|
}>;
|
|
67
32
|
/**
|
|
@@ -71,7 +36,7 @@ export declare const BLOCKQUOTE_RULE: MarkupRule<{
|
|
|
71
36
|
* - If there's no closing fence the code block will run to the end of the current string.
|
|
72
37
|
* - Markdown-style four-space indent syntax is not supported (only fenced code, since it's easier to use).
|
|
73
38
|
*/
|
|
74
|
-
export declare const FENCED_CODE_RULE:
|
|
39
|
+
export declare const FENCED_CODE_RULE: NamedRegExpMarkupRule<{
|
|
75
40
|
wrap: string;
|
|
76
41
|
title?: string;
|
|
77
42
|
code: string;
|
|
@@ -80,23 +45,14 @@ export declare const FENCED_CODE_RULE: MarkupRule<{
|
|
|
80
45
|
* Paragraph.
|
|
81
46
|
* - When ordering rules, paragraph should go after other "block" context elements (because it has a very generous capture).
|
|
82
47
|
*/
|
|
83
|
-
export declare const PARAGRAPH_RULE:
|
|
48
|
+
export declare const PARAGRAPH_RULE: NamedRegExpMarkupRule<{
|
|
84
49
|
paragraph: string;
|
|
85
50
|
}>;
|
|
86
|
-
/**
|
|
87
|
-
|
|
88
|
-
* - Used by `URL_RULE~ and `LINK_RULE`
|
|
89
|
-
* - Validates that the link is a valid URL (using `getOptionalURL()` to resolve relative links relative to `options.url`).
|
|
90
|
-
* - Validates that the link's URL scheme is in the `options.schemes` whitelist (defaults to `http` and `https`).
|
|
91
|
-
* - Generates a default title for the link using `formatURL()` (e.g. `shax.com/my/dir`).
|
|
92
|
-
*/
|
|
93
|
-
export declare function getLinkMatcher(regexp: NamedRegExp<{
|
|
94
|
-
title?: string;
|
|
95
|
-
href: string;
|
|
96
|
-
}>): MarkupMatcher<{
|
|
51
|
+
/** Render function for URL and LINK rules. */
|
|
52
|
+
export declare function renderLinkRule({ href, title }: {
|
|
97
53
|
title: string;
|
|
98
54
|
href: string;
|
|
99
|
-
}
|
|
55
|
+
}, { rel }: MarkupOptions): JSXElement;
|
|
100
56
|
/**
|
|
101
57
|
* Autolinked URL starts with `http:` or `https:` or `mailto:` (any scheme in `options.schemes`) and matches an unlimited number of non-space characters.
|
|
102
58
|
* - If followed by space and then text in `()` round or `[]` square brackets that will be used as the title, e.g. `http://google.com/maps (Google Maps)` or `http://google.com/maps [Google Maps]` (this syntax is from Todoist and maybe other things too).
|
|
@@ -108,10 +64,7 @@ export declare const URL_REGEXP: NamedRegExp<{
|
|
|
108
64
|
title?: string;
|
|
109
65
|
href: string;
|
|
110
66
|
}>;
|
|
111
|
-
export declare const URL_RULE:
|
|
112
|
-
title: string;
|
|
113
|
-
href: string;
|
|
114
|
-
}>;
|
|
67
|
+
export declare const URL_RULE: LinkRegExpMarkupRule;
|
|
115
68
|
/**
|
|
116
69
|
* Markdown-style link.
|
|
117
70
|
* - Link in standard Markdown format, e.g. `[Google Maps](http://google.com/maps)`
|
|
@@ -124,10 +77,7 @@ export declare const LINK_REGEXP: NamedRegExp<{
|
|
|
124
77
|
title: string;
|
|
125
78
|
href: string;
|
|
126
79
|
}>;
|
|
127
|
-
export declare const LINK_RULE:
|
|
128
|
-
title: string;
|
|
129
|
-
href: string;
|
|
130
|
-
}>;
|
|
80
|
+
export declare const LINK_RULE: LinkRegExpMarkupRule;
|
|
131
81
|
/**
|
|
132
82
|
* Inline code.
|
|
133
83
|
* - Text surrounded by one or more "`" backtick tilde characters.
|
|
@@ -135,7 +85,7 @@ export declare const LINK_RULE: MarkupRule<{
|
|
|
135
85
|
* - Closing characters must exactly match opening characters.
|
|
136
86
|
* - Same as Markdown syntax.
|
|
137
87
|
*/
|
|
138
|
-
export declare const CODE_RULE:
|
|
88
|
+
export declare const CODE_RULE: NamedRegExpMarkupRule<{
|
|
139
89
|
code: string;
|
|
140
90
|
}>;
|
|
141
91
|
/**
|
|
@@ -160,7 +110,7 @@ declare const INLINE_CHARS: {
|
|
|
160
110
|
"=": string;
|
|
161
111
|
":": string;
|
|
162
112
|
};
|
|
163
|
-
export declare const INLINE_RULE:
|
|
113
|
+
export declare const INLINE_RULE: NamedRegExpMarkupRule<{
|
|
164
114
|
char: keyof typeof INLINE_CHARS;
|
|
165
115
|
wrap: string;
|
|
166
116
|
text: string;
|
|
@@ -173,7 +123,7 @@ export declare const INLINE_RULE: MarkupRule<{
|
|
|
173
123
|
* - This is more intuitive (a linebreak becomes a linebreak is isn't silently ignored).
|
|
174
124
|
* - This works better with textareas that wrap text (since manually breaking up long lines is no longer necessary).
|
|
175
125
|
*/
|
|
176
|
-
export declare const LINEBREAK_RULE:
|
|
126
|
+
export declare const LINEBREAK_RULE: RegExpMarkupRule;
|
|
177
127
|
/**
|
|
178
128
|
* All markup rules.
|
|
179
129
|
* - Syntax parsed by `renderMarkup()` is defined entirely by the list of rules (i.e. not by code).
|
package/markup/rules.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* eslint-disable import/export */
|
|
2
2
|
import { getRegExp } from "../util/regexp.js";
|
|
3
|
-
import { formatURL, getOptionalURL } from "../util/url.js";
|
|
4
3
|
import { getBlockRegExp, getLineRegExp, BLOCK_REGEXP, LINE_REGEXP, WordRegExp } from "./regexp.js";
|
|
4
|
+
import { LinkRegExpMarkupRule, NamedRegExpMarkupRule, RegExpMarkupRule } from "./rule.js";
|
|
5
5
|
/** React security symbol — see https://github.com/facebook/react/pull/4832 */
|
|
6
6
|
const $$typeof = Symbol.for("react.element");
|
|
7
7
|
/**
|
|
@@ -10,18 +10,13 @@ const $$typeof = Symbol.for("react.element");
|
|
|
10
10
|
* - Same as Markdown syntax.
|
|
11
11
|
* - Markdown's underline syntax is not supported (for simplification).
|
|
12
12
|
*/
|
|
13
|
-
export const HEADING_RULE = {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
props: { children: heading.trim() },
|
|
21
|
-
}),
|
|
22
|
-
contexts: ["block"],
|
|
23
|
-
subcontext: "inline",
|
|
24
|
-
};
|
|
13
|
+
export const HEADING_RULE = new NamedRegExpMarkupRule(getLineRegExp(`(?<prefix>#{1,6}) +(?<heading>${LINE_REGEXP.source})`), ({ prefix, heading }) => ({
|
|
14
|
+
type: `h${prefix.length}`,
|
|
15
|
+
key: null,
|
|
16
|
+
ref: null,
|
|
17
|
+
$$typeof,
|
|
18
|
+
props: { children: heading.trim() },
|
|
19
|
+
}), ["block"], "inline");
|
|
25
20
|
/**
|
|
26
21
|
* Separator (horizontal rule / thematic break).
|
|
27
22
|
* - Same as Markdown syntax but also allows `•` bullet character (in addition to `-` dash, `+` plus, `*` asterisk, `_` underscore).
|
|
@@ -29,17 +24,13 @@ export const HEADING_RULE = {
|
|
|
29
24
|
* - Character must be the same every time (can't mix)
|
|
30
25
|
* - Might have infinite number of spaces between the characters.
|
|
31
26
|
*/
|
|
32
|
-
export const SEPARATOR_RULE = {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
props: {},
|
|
40
|
-
}),
|
|
41
|
-
contexts: ["block"],
|
|
42
|
-
};
|
|
27
|
+
export const SEPARATOR_RULE = new RegExpMarkupRule(getLineRegExp("([-*•+_=])(?: *\\1){2,}"), () => ({
|
|
28
|
+
type: "hr",
|
|
29
|
+
key: null,
|
|
30
|
+
ref: null,
|
|
31
|
+
$$typeof,
|
|
32
|
+
props: {},
|
|
33
|
+
}), ["block"]);
|
|
43
34
|
/**
|
|
44
35
|
* Unordered list.
|
|
45
36
|
* - Roughly the same syntax as Markdown (might be some differences with indenting).
|
|
@@ -50,18 +41,13 @@ export const SEPARATOR_RULE = {
|
|
|
50
41
|
const UNORDERED_PREFIX = "[-*•+] +";
|
|
51
42
|
const UNORDERED_SPLIT = new RegExp(`(?:^|\n)+${UNORDERED_PREFIX}`, "g");
|
|
52
43
|
const UNORDERED_INDENT = /^\t/gm;
|
|
53
|
-
export const UNORDERED_RULE = {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
props: { children: list.split(UNORDERED_SPLIT).filter(Boolean).map(_mapUnordered) },
|
|
61
|
-
}),
|
|
62
|
-
contexts: ["block", "list"],
|
|
63
|
-
subcontext: "list",
|
|
64
|
-
};
|
|
44
|
+
export const UNORDERED_RULE = new NamedRegExpMarkupRule(getBlockRegExp(`(?<list>${UNORDERED_PREFIX}${BLOCK_REGEXP.source})`), ({ list }) => ({
|
|
45
|
+
type: "ul",
|
|
46
|
+
key: null,
|
|
47
|
+
ref: null,
|
|
48
|
+
$$typeof,
|
|
49
|
+
props: { children: list.split(UNORDERED_SPLIT).filter(Boolean).map(_mapUnordered) },
|
|
50
|
+
}), ["block", "list"], "list");
|
|
65
51
|
const _mapUnordered = (item, key) => ({
|
|
66
52
|
type: "li",
|
|
67
53
|
key,
|
|
@@ -77,18 +63,13 @@ const _mapUnordered = (item, key) => ({
|
|
|
77
63
|
const ORDERED_PREFIX = "[1-9][0-9]{0,8}[.):] +"; // Number for a numbered list, e.g. `1.` or `2)` or `3:`
|
|
78
64
|
const ORDERED_SPLIT = new RegExp(`\n+(?=${ORDERED_PREFIX})`, "g");
|
|
79
65
|
const ORDERED_INDENT = UNORDERED_INDENT;
|
|
80
|
-
export const ORDERED_RULE = {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
props: { children: list.split(ORDERED_SPLIT).map(_mapOrdered) },
|
|
88
|
-
}),
|
|
89
|
-
contexts: ["block", "list"],
|
|
90
|
-
subcontext: "list",
|
|
91
|
-
};
|
|
66
|
+
export const ORDERED_RULE = new NamedRegExpMarkupRule(getBlockRegExp(`(?<list>${ORDERED_PREFIX}${BLOCK_REGEXP.source})`), ({ list }) => ({
|
|
67
|
+
type: "ol",
|
|
68
|
+
key: null,
|
|
69
|
+
ref: null,
|
|
70
|
+
$$typeof,
|
|
71
|
+
props: { children: list.split(ORDERED_SPLIT).map(_mapOrdered) },
|
|
72
|
+
}), ["block", "list"], "list");
|
|
92
73
|
const _mapOrdered = (item, key) => ({
|
|
93
74
|
type: "li",
|
|
94
75
|
key,
|
|
@@ -110,18 +91,13 @@ const _mapOrdered = (item, key) => ({
|
|
|
110
91
|
*/
|
|
111
92
|
const BLOCKQUOTE_PREFIX = "> *";
|
|
112
93
|
const BLOCKQUOTE_INDENT = new RegExp(`^${BLOCKQUOTE_PREFIX}`, "gm");
|
|
113
|
-
export const BLOCKQUOTE_RULE = {
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
props: { children: quote.replace(BLOCKQUOTE_INDENT, "") },
|
|
121
|
-
}),
|
|
122
|
-
contexts: ["block", "list"],
|
|
123
|
-
subcontext: "block",
|
|
124
|
-
};
|
|
94
|
+
export const BLOCKQUOTE_RULE = new NamedRegExpMarkupRule(getLineRegExp(`(?<quote>${BLOCKQUOTE_PREFIX}${LINE_REGEXP.source}(?:\n${BLOCKQUOTE_PREFIX}${LINE_REGEXP.source})*)`), ({ quote }) => ({
|
|
95
|
+
type: "blockquote",
|
|
96
|
+
key: null,
|
|
97
|
+
ref: null,
|
|
98
|
+
$$typeof,
|
|
99
|
+
props: { children: quote.replace(BLOCKQUOTE_INDENT, "") },
|
|
100
|
+
}), ["block", "list"], "block");
|
|
125
101
|
/**
|
|
126
102
|
* Fenced code blocks
|
|
127
103
|
* - Same as Markdown syntax.
|
|
@@ -129,62 +105,42 @@ export const BLOCKQUOTE_RULE = {
|
|
|
129
105
|
* - If there's no closing fence the code block will run to the end of the current string.
|
|
130
106
|
* - Markdown-style four-space indent syntax is not supported (only fenced code, since it's easier to use).
|
|
131
107
|
*/
|
|
132
|
-
export const FENCED_CODE_RULE =
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
props: { title: (title === null || title === void 0 ? void 0 : title.trim()) || undefined, children: code.trim() },
|
|
147
|
-
},
|
|
108
|
+
export const FENCED_CODE_RULE = new NamedRegExpMarkupRule(
|
|
109
|
+
// Matcher has its own end that only stops when it reaches a matching closing fence or the end of the string.
|
|
110
|
+
getLineRegExp(`(?<wrap>\`{3,}|~{3,}) *(?<title>${LINE_REGEXP.source})\n(?<code>${BLOCK_REGEXP.source})`, `(?:\n\\k<wrap>|$)`), ({ title, code }) => ({
|
|
111
|
+
type: "pre",
|
|
112
|
+
key: null,
|
|
113
|
+
ref: null,
|
|
114
|
+
$$typeof,
|
|
115
|
+
props: {
|
|
116
|
+
children: {
|
|
117
|
+
type: "code",
|
|
118
|
+
key: null,
|
|
119
|
+
ref: null,
|
|
120
|
+
$$typeof,
|
|
121
|
+
props: { title: (title === null || title === void 0 ? void 0 : title.trim()) || undefined, children: code.trim() },
|
|
148
122
|
},
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
priority: 10, // Higher priority than other blocks so e.g. lists inside fenced code don't become lists.
|
|
152
|
-
};
|
|
123
|
+
},
|
|
124
|
+
}), ["block", "list"], null, 10);
|
|
153
125
|
/**
|
|
154
126
|
* Paragraph.
|
|
155
127
|
* - When ordering rules, paragraph should go after other "block" context elements (because it has a very generous capture).
|
|
156
128
|
*/
|
|
157
|
-
export const PARAGRAPH_RULE = {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
129
|
+
export const PARAGRAPH_RULE = new NamedRegExpMarkupRule(getBlockRegExp(`(?<paragraph>${BLOCK_REGEXP.source})`), ({ paragraph }) => ({
|
|
130
|
+
type: `p`,
|
|
131
|
+
key: null,
|
|
132
|
+
ref: null,
|
|
133
|
+
$$typeof,
|
|
134
|
+
props: { children: paragraph.trim() },
|
|
135
|
+
}), ["block"], "inline", -10);
|
|
136
|
+
/** Render function for URL and LINK rules. */
|
|
137
|
+
export function renderLinkRule({ href, title }, { rel }) {
|
|
138
|
+
return {
|
|
139
|
+
type: "a",
|
|
161
140
|
key: null,
|
|
162
141
|
ref: null,
|
|
163
142
|
$$typeof,
|
|
164
|
-
props: { children:
|
|
165
|
-
}),
|
|
166
|
-
contexts: ["block"],
|
|
167
|
-
subcontext: "inline",
|
|
168
|
-
priority: -10, // Lower precedence than other blocks so it matches last and paragraphs can be broken by other blocks.
|
|
169
|
-
};
|
|
170
|
-
/**
|
|
171
|
-
* Function that checks a link against the schemas allowed by rendering.
|
|
172
|
-
* - Used by `URL_RULE~ and `LINK_RULE`
|
|
173
|
-
* - Validates that the link is a valid URL (using `getOptionalURL()` to resolve relative links relative to `options.url`).
|
|
174
|
-
* - Validates that the link's URL scheme is in the `options.schemes` whitelist (defaults to `http` and `https`).
|
|
175
|
-
* - Generates a default title for the link using `formatURL()` (e.g. `shax.com/my/dir`).
|
|
176
|
-
*/
|
|
177
|
-
export function getLinkMatcher(regexp) {
|
|
178
|
-
return (input, { schemes, url: base }) => {
|
|
179
|
-
const match = regexp.exec(input);
|
|
180
|
-
if (match) {
|
|
181
|
-
const { 0: first, index, groups } = match;
|
|
182
|
-
const { href, title } = groups;
|
|
183
|
-
const url = getOptionalURL(href, base);
|
|
184
|
-
if (url && schemes.includes(url.protocol)) {
|
|
185
|
-
return { 0: first, index, groups: { href: url.href, title: (title === null || title === void 0 ? void 0 : title.trim()) || formatURL(url) } };
|
|
186
|
-
}
|
|
187
|
-
}
|
|
143
|
+
props: { children: title, href, rel },
|
|
188
144
|
};
|
|
189
145
|
}
|
|
190
146
|
/**
|
|
@@ -195,18 +151,7 @@ export function getLinkMatcher(regexp) {
|
|
|
195
151
|
* - For security only schemes that appear in `options.schemes` will match (defaults to `http:` and `https:`).
|
|
196
152
|
*/
|
|
197
153
|
export const URL_REGEXP = getRegExp(/(?<href>[a-z]+:[-$_@.&!*,=;/#?:%a-zA-Z0-9]+)(?: +(?:\((?<title>[^)]*?)\)))?/);
|
|
198
|
-
export const URL_RULE =
|
|
199
|
-
match: getLinkMatcher(URL_REGEXP),
|
|
200
|
-
render: ({ href, title }, { rel }) => ({
|
|
201
|
-
type: "a",
|
|
202
|
-
key: null,
|
|
203
|
-
ref: null,
|
|
204
|
-
$$typeof,
|
|
205
|
-
props: { children: title, href, rel },
|
|
206
|
-
}),
|
|
207
|
-
contexts: ["inline", "list"],
|
|
208
|
-
subcontext: "link",
|
|
209
|
-
};
|
|
154
|
+
export const URL_RULE = new LinkRegExpMarkupRule(URL_REGEXP, renderLinkRule, ["inline", "list"], "link");
|
|
210
155
|
/**
|
|
211
156
|
* Markdown-style link.
|
|
212
157
|
* - Link in standard Markdown format, e.g. `[Google Maps](http://google.com/maps)`
|
|
@@ -216,10 +161,7 @@ export const URL_RULE = {
|
|
|
216
161
|
* - For security only `http://` or `https://` links will work (if invalid the unparsed text will be returned).
|
|
217
162
|
*/
|
|
218
163
|
export const LINK_REGEXP = getRegExp(/\[(?<title>[^\]]*?)\]\((?<href>[^)]*?)\)/);
|
|
219
|
-
export const LINK_RULE =
|
|
220
|
-
...URL_RULE,
|
|
221
|
-
match: getLinkMatcher(LINK_REGEXP),
|
|
222
|
-
};
|
|
164
|
+
export const LINK_RULE = new LinkRegExpMarkupRule(LINK_REGEXP, renderLinkRule, ["inline", "list"], "link");
|
|
223
165
|
/**
|
|
224
166
|
* Inline code.
|
|
225
167
|
* - Text surrounded by one or more "`" backtick tilde characters.
|
|
@@ -227,18 +169,13 @@ export const LINK_RULE = {
|
|
|
227
169
|
* - Closing characters must exactly match opening characters.
|
|
228
170
|
* - Same as Markdown syntax.
|
|
229
171
|
*/
|
|
230
|
-
export const CODE_RULE = {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
props: { children: code },
|
|
238
|
-
}),
|
|
239
|
-
contexts: ["inline", "list"],
|
|
240
|
-
priority: 10, // Higher priority than e.g. `strong` or `em` (from CommonMark spec: "Code span backticks have higher precedence than any other inline constructs except HTML tags and autolinks.")
|
|
241
|
-
};
|
|
172
|
+
export const CODE_RULE = new NamedRegExpMarkupRule(new RegExp(`(?<wrap>\`+)(?<code>${BLOCK_REGEXP.source})\\k<wrap>`), ({ code }) => ({
|
|
173
|
+
type: "code",
|
|
174
|
+
key: null,
|
|
175
|
+
ref: null,
|
|
176
|
+
$$typeof,
|
|
177
|
+
props: { children: code },
|
|
178
|
+
}), ["inline", "list"], null, 10);
|
|
242
179
|
/**
|
|
243
180
|
* Inline strong, emphasis, insert, delete, highlight.
|
|
244
181
|
* - Inline strong text wrapped in one or more `*` asterisks.
|
|
@@ -253,18 +190,14 @@ export const CODE_RULE = {
|
|
|
253
190
|
* - Different to Markdown: strong is always surrounded by `*asterisks*` and emphasis is always surrounded by `_underscores_` (strong isn't 'double emphasis').
|
|
254
191
|
*/
|
|
255
192
|
const INLINE_CHARS = { "-": "del", "~": "del", "+": "ins", "*": "strong", "_": "em", "=": "mark", ":": "mark" }; // Hyphen must be first so it works when we use the keys as a character class.
|
|
256
|
-
export const INLINE_RULE = {
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}),
|
|
265
|
-
contexts: ["inline", "list", "link"],
|
|
266
|
-
subcontext: "inline",
|
|
267
|
-
};
|
|
193
|
+
export const INLINE_RULE = new NamedRegExpMarkupRule(new WordRegExp(`(?<wrap>(?<char>[${Object.keys(INLINE_CHARS).join("")}])+)(?<text>(?!\\k<char>)\\S|(?!\\k<char>)\\S[\\s\\S]*?(?!\\k<char>)\\S)\\k<wrap>`), // prettier-ignore
|
|
194
|
+
({ char, text }) => ({
|
|
195
|
+
type: INLINE_CHARS[char],
|
|
196
|
+
key: null,
|
|
197
|
+
ref: null,
|
|
198
|
+
$$typeof,
|
|
199
|
+
props: { children: text },
|
|
200
|
+
}), ["inline", "list", "link"], "inline");
|
|
268
201
|
/**
|
|
269
202
|
* Hard linebreak (`<br />` tag).
|
|
270
203
|
* - Any line break in a paragraph will become a hard `<br />` tag.
|
|
@@ -273,18 +206,13 @@ export const INLINE_RULE = {
|
|
|
273
206
|
* - This is more intuitive (a linebreak becomes a linebreak is isn't silently ignored).
|
|
274
207
|
* - This works better with textareas that wrap text (since manually breaking up long lines is no longer necessary).
|
|
275
208
|
*/
|
|
276
|
-
export const LINEBREAK_RULE = {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
props: {},
|
|
284
|
-
}),
|
|
285
|
-
contexts: ["inline", "list", "link"],
|
|
286
|
-
subcontext: "inline",
|
|
287
|
-
};
|
|
209
|
+
export const LINEBREAK_RULE = new RegExpMarkupRule(/\n/, () => ({
|
|
210
|
+
type: "br",
|
|
211
|
+
key: null,
|
|
212
|
+
ref: null,
|
|
213
|
+
$$typeof,
|
|
214
|
+
props: {},
|
|
215
|
+
}), ["inline", "list", "link"], "inline");
|
|
288
216
|
/**
|
|
289
217
|
* All markup rules.
|
|
290
218
|
* - Syntax parsed by `renderMarkup()` is defined entirely by the list of rules (i.e. not by code).
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"state-management",
|
|
12
12
|
"query-builder"
|
|
13
13
|
],
|
|
14
|
-
"version": "1.86.
|
|
14
|
+
"version": "1.86.2",
|
|
15
15
|
"repository": "https://github.com/dhoulb/shelving",
|
|
16
16
|
"author": "Dave Houlbrooke <dave@shax.com>",
|
|
17
17
|
"license": "0BSD",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"sideEffects": false,
|
|
44
44
|
"engineStrict": true,
|
|
45
45
|
"engines": {
|
|
46
|
-
"node": ">=
|
|
46
|
+
"node": ">=16.0.0"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
49
|
"fix": "npm run fix:prettier && npm run fix:eslint",
|
|
@@ -64,26 +64,26 @@
|
|
|
64
64
|
"build:jest": "node --experimental-vm-modules node_modules/jest/bin/jest.js --config=jest.config.build.cjs"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@google-cloud/firestore": "^6.4.
|
|
68
|
-
"@types/jest": "^29.
|
|
69
|
-
"@types/react": "^18.0.
|
|
70
|
-
"@types/react-dom": "^18.0.
|
|
71
|
-
"@typescript-eslint/eslint-plugin": "^5.
|
|
72
|
-
"@typescript-eslint/parser": "^5.
|
|
73
|
-
"dpdm": "^3.
|
|
74
|
-
"esbuild": "^0.15.
|
|
67
|
+
"@google-cloud/firestore": "^6.4.2",
|
|
68
|
+
"@types/jest": "^29.4.0",
|
|
69
|
+
"@types/react": "^18.0.27",
|
|
70
|
+
"@types/react-dom": "^18.0.10",
|
|
71
|
+
"@typescript-eslint/eslint-plugin": "^5.49.0",
|
|
72
|
+
"@typescript-eslint/parser": "^5.49.0",
|
|
73
|
+
"dpdm": "^3.11.0",
|
|
74
|
+
"esbuild": "^0.15.18",
|
|
75
75
|
"esbuild-jest": "^0.5.0",
|
|
76
|
-
"eslint": "^8.
|
|
77
|
-
"eslint-config-prettier": "^8.
|
|
78
|
-
"eslint-plugin-import": "^2.
|
|
76
|
+
"eslint": "^8.33.0",
|
|
77
|
+
"eslint-config-prettier": "^8.6.0",
|
|
78
|
+
"eslint-plugin-import": "^2.27.5",
|
|
79
79
|
"eslint-plugin-prettier": "^4.0.0",
|
|
80
|
-
"firebase": "^9.
|
|
81
|
-
"jest": "^29.
|
|
80
|
+
"firebase": "^9.16.0",
|
|
81
|
+
"jest": "^29.4.1",
|
|
82
82
|
"jest-ts-webcompat-resolver": "^1.0.0",
|
|
83
|
-
"prettier": "^2.
|
|
83
|
+
"prettier": "^2.8.3",
|
|
84
84
|
"react": "^18.1.0",
|
|
85
85
|
"react-dom": "^18.1.0",
|
|
86
|
-
"typescript": "^4.
|
|
86
|
+
"typescript": "^4.9.4"
|
|
87
87
|
},
|
|
88
88
|
"peerDependencies": {
|
|
89
89
|
"@google-cloud/firestore": ">=4.0.0",
|
package/react/useItem.js
CHANGED
|
@@ -9,10 +9,18 @@ import { useState } from "./useState.js";
|
|
|
9
9
|
import { useCache } from "./useCache.js";
|
|
10
10
|
/** Hold the current state of a item. */
|
|
11
11
|
export class ItemState extends State {
|
|
12
|
+
/** Get the data of the item (throws `RequiredError` if item doesn't exist). */
|
|
13
|
+
get data() {
|
|
14
|
+
return getData(this.value);
|
|
15
|
+
}
|
|
16
|
+
/** Does the item exist (i.e. its value isn't `null`)? */
|
|
17
|
+
get exists() {
|
|
18
|
+
return !!this.value;
|
|
19
|
+
}
|
|
12
20
|
constructor(ref) {
|
|
13
|
-
var _a;
|
|
14
21
|
const { db, collection, id } = ref;
|
|
15
|
-
const
|
|
22
|
+
const cache = getOptionalSource(CacheProvider, db.provider);
|
|
23
|
+
const table = cache === null || cache === void 0 ? void 0 : cache.memory.getTable(collection);
|
|
16
24
|
const time = table ? table.getItemTime(id) : null;
|
|
17
25
|
const isCached = typeof time === "number";
|
|
18
26
|
super(table && isCached ? table.getItem(id) : State.NOVALUE, table ? new LazyDeferredSequence(() => this.from(table.getCachedItemSequence(id))) : undefined);
|
|
@@ -28,14 +36,6 @@ export class ItemState extends State {
|
|
|
28
36
|
if (this.loading)
|
|
29
37
|
this.refresh();
|
|
30
38
|
}
|
|
31
|
-
/** Get the data of the item (throws `RequiredError` if item doesn't exist). */
|
|
32
|
-
get data() {
|
|
33
|
-
return getData(this.value);
|
|
34
|
-
}
|
|
35
|
-
/** Does the item exist (i.e. its value isn't `null`)? */
|
|
36
|
-
get exists() {
|
|
37
|
-
return !!this.value;
|
|
38
|
-
}
|
|
39
39
|
async _refresh() {
|
|
40
40
|
this.busy.set(true);
|
|
41
41
|
try {
|
package/react/useQuery.js
CHANGED
|
@@ -9,35 +9,6 @@ import { useState } from "./useState.js";
|
|
|
9
9
|
import { useCache } from "./useCache.js";
|
|
10
10
|
/** Hold the current state of a query. */
|
|
11
11
|
export class QueryState extends State {
|
|
12
|
-
constructor(ref) {
|
|
13
|
-
var _a;
|
|
14
|
-
const { db, collection, limit } = ref;
|
|
15
|
-
const table = (_a = getOptionalSource(CacheProvider, db.provider)) === null || _a === void 0 ? void 0 : _a.memory.getTable(collection);
|
|
16
|
-
const time = table ? table.getQueryTime(ref) : null;
|
|
17
|
-
const isCached = typeof time === "number";
|
|
18
|
-
super(table && isCached ? table.getQuery(ref) : State.NOVALUE, table ? new LazyDeferredSequence(() => this.from(table.getCachedQuerySequence(ref))) : undefined);
|
|
19
|
-
this.busy = new BooleanState();
|
|
20
|
-
this._hasMore = false;
|
|
21
|
-
/** Refresh this state from the source provider. */
|
|
22
|
-
this.refresh = () => {
|
|
23
|
-
if (!this.busy.value)
|
|
24
|
-
void this._refresh();
|
|
25
|
-
};
|
|
26
|
-
/**
|
|
27
|
-
* Load more items after the last once.
|
|
28
|
-
* - Promise that needs to be handled.
|
|
29
|
-
*/
|
|
30
|
-
this.loadMore = () => {
|
|
31
|
-
if (!this.busy.value)
|
|
32
|
-
void this._loadMore();
|
|
33
|
-
};
|
|
34
|
-
this._time = time;
|
|
35
|
-
this.ref = ref;
|
|
36
|
-
this.limit = limit !== null && limit !== void 0 ? limit : Infinity;
|
|
37
|
-
// Queue a request to refresh the value if it doesn't exist.
|
|
38
|
-
if (this.loading)
|
|
39
|
-
this.refresh();
|
|
40
|
-
}
|
|
41
12
|
/** Can more items be loaded after the current result. */
|
|
42
13
|
get hasMore() {
|
|
43
14
|
return this._hasMore;
|
|
@@ -66,6 +37,35 @@ export class QueryState extends State {
|
|
|
66
37
|
get count() {
|
|
67
38
|
return this.value.length;
|
|
68
39
|
}
|
|
40
|
+
constructor(ref) {
|
|
41
|
+
const { db, collection, limit } = ref;
|
|
42
|
+
const cache = getOptionalSource(CacheProvider, db.provider);
|
|
43
|
+
const table = cache === null || cache === void 0 ? void 0 : cache.memory.getTable(collection);
|
|
44
|
+
const time = table ? table.getQueryTime(ref) : null;
|
|
45
|
+
const isCached = typeof time === "number";
|
|
46
|
+
super(table && isCached ? table.getQuery(ref) : State.NOVALUE, table ? new LazyDeferredSequence(() => this.from(table.getCachedQuerySequence(ref))) : undefined);
|
|
47
|
+
this.busy = new BooleanState();
|
|
48
|
+
this._hasMore = false;
|
|
49
|
+
/** Refresh this state from the source provider. */
|
|
50
|
+
this.refresh = () => {
|
|
51
|
+
if (!this.busy.value)
|
|
52
|
+
void this._refresh();
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Load more items after the last once.
|
|
56
|
+
* - Promise that needs to be handled.
|
|
57
|
+
*/
|
|
58
|
+
this.loadMore = () => {
|
|
59
|
+
if (!this.busy.value)
|
|
60
|
+
void this._loadMore();
|
|
61
|
+
};
|
|
62
|
+
this._time = time;
|
|
63
|
+
this.ref = ref;
|
|
64
|
+
this.limit = limit !== null && limit !== void 0 ? limit : Infinity;
|
|
65
|
+
// Queue a request to refresh the value if it doesn't exist.
|
|
66
|
+
if (this.loading)
|
|
67
|
+
this.refresh();
|
|
68
|
+
}
|
|
69
69
|
async _refresh() {
|
|
70
70
|
this.busy.set(true);
|
|
71
71
|
try {
|