This is an automated email from the ASF dual-hosted git repository. gerben pushed a commit to branch simpler-matcher-creation in repository https://gitbox.apache.org/repos/asf/incubator-annotator.git
commit ae3c0c9471e02e4186d38325a3d8ef6363d06bda Author: Gerben <[email protected]> AuthorDate: Wed Sep 2 18:57:37 2020 +0200 First (failing) attempt at createTypedMatcherCreator --- packages/selector/src/index.ts | 27 +++++++++++++++++++++++++++ packages/selector/src/types.ts | 3 +++ web/demo/index.js | 16 ++++------------ 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/packages/selector/src/index.ts b/packages/selector/src/index.ts index ffbf9d2..b95a858 100644 --- a/packages/selector/src/index.ts +++ b/packages/selector/src/index.ts @@ -23,6 +23,33 @@ import type { Matcher, Selector } from './types'; export type { Matcher, Selector } from './types'; export type { CssSelector, RangeSelector, TextQuoteSelector } from './types'; +export function createTypedMatcherCreator<TSelectorType extends string, TScope, TMatch extends TScope>( + typeToMatcher: + | Record<TSelectorType, ((selector: Selector) => Matcher<TScope, TMatch>)> + | ((type: TSelectorType) => (selector: Selector) => Matcher<TScope, TMatch>), +): (selector: Selector & { type: TSelectorType }) => Matcher<TScope, TMatch> { + + function createMatcher(selector: Selector & { type: TSelectorType }): Matcher<TScope, TMatch> { + const type = selector.type; + + if (type === undefined) { + throw new TypeError('Selector does not specify its type'); + } + + const innerCreateMatcher = (typeof typeToMatcher === 'function') + ? typeToMatcher(type) + : typeToMatcher[type]; + + if (innerCreateMatcher === undefined) { + throw new TypeError(`Unsupported selector type: ${type}`); + } + + return innerCreateMatcher(selector); + } + + return makeRefinable(createMatcher); +} + export function makeRefinable< TSelector extends Selector, TScope, diff --git a/packages/selector/src/types.ts b/packages/selector/src/types.ts index 7bfa0cd..58428f7 100644 --- a/packages/selector/src/types.ts +++ b/packages/selector/src/types.ts @@ -20,8 +20,11 @@ export interface Selector { refinedBy?: this; + type?: SelectorType; } +export type SelectorType = string; // not enumerating known options: we allow extensibility. + export interface CssSelector extends Selector { type: 'CssSelector'; value: string; diff --git a/web/demo/index.js b/web/demo/index.js index 6de6493..16c9d03 100644 --- a/web/demo/index.js +++ b/web/demo/index.js @@ -26,7 +26,7 @@ import { describeTextQuote, highlightRange, } from '@annotator/dom'; -import { makeRefinable } from '@annotator/selector'; +import { createTypedMatcherCreator } from '@annotator/selector'; const EXAMPLE_SELECTORS = [ { @@ -91,17 +91,9 @@ function cleanup() { target.normalize(); } -const createMatcher = makeRefinable((selector) => { - const innerCreateMatcher = { - TextQuoteSelector: createTextQuoteSelectorMatcher, - RangeSelector: makeCreateRangeSelectorMatcher(createMatcher), - }[selector.type]; - - if (!innerCreateMatcher) { - throw new Error(`Unsupported selector type: ${selector.type}`); - } - - return innerCreateMatcher(selector); +const createMatcher = createTypedMatcherCreator({ + TextQuoteSelector: createTextQuoteSelectorMatcher, + RangeSelector: makeCreateRangeSelectorMatcher(createMatcher), // FIXME This goes wrong. Tough! }); async function anchor(selector) {
