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) {

Reply via email to