alinea 0.5.5 → 0.5.6

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.
Files changed (38) hide show
  1. package/dist/backend/Database.js +3 -2
  2. package/dist/backend/Store.js +1 -1
  3. package/dist/backend/resolver/EntryResolver.js +5 -2
  4. package/dist/chunks/{chunk-TY7XOXM3.js → chunk-CYNFUAZ7.js} +3 -1
  5. package/dist/chunks/{chunk-ULWFKWBM.js → chunk-HWXESJ6U.js} +1 -1
  6. package/dist/chunks/{chunk-VRXHB6DJ.js → chunk-LMUDRU2U.js} +2 -1
  7. package/dist/chunks/{sql.js-75HGQX6U.js → sql.js-RSY2XONK.js} +1 -1
  8. package/dist/cli/Generate.js +1 -1
  9. package/dist/cli/Serve.js +1 -1
  10. package/dist/cli/bin.js +1 -1
  11. package/dist/cli/generate/GenerateDashboard.js +1 -1
  12. package/dist/cloud/server/CloudAuthServer.js +1 -1
  13. package/dist/core/EntrySearch.d.ts +1 -0
  14. package/dist/core/EntrySearch.js +1 -0
  15. package/dist/core/Shape.d.ts +1 -1
  16. package/dist/core/Type.d.ts +1 -0
  17. package/dist/core/Type.js +4 -0
  18. package/dist/core/Type.test.d.ts +1 -0
  19. package/dist/core/driver/TestDriver.js +1 -1
  20. package/dist/core/field/RichTextField.d.ts +3 -1
  21. package/dist/core/field/RichTextField.js +2 -1
  22. package/dist/core/field/ScalarField.d.ts +3 -1
  23. package/dist/core/field/ScalarField.js +5 -1
  24. package/dist/core/shape/ListShape.d.ts +1 -0
  25. package/dist/core/shape/ListShape.js +13 -0
  26. package/dist/core/shape/RecordShape.d.ts +1 -0
  27. package/dist/core/shape/RecordShape.js +8 -0
  28. package/dist/core/shape/RichTextShape.d.ts +5 -2
  29. package/dist/core/shape/RichTextShape.js +26 -1
  30. package/dist/core/shape/ScalarShape.d.ts +3 -1
  31. package/dist/core/shape/ScalarShape.js +8 -1
  32. package/dist/core/shape/UnionShape.d.ts +1 -0
  33. package/dist/core/shape/UnionShape.js +16 -0
  34. package/dist/core/util/EntryRows.js +4 -1
  35. package/dist/dashboard/util/PersistentStore.js +1 -1
  36. package/dist/input/richtext/RichTextField.d.ts +2 -6
  37. package/dist/input/text/TextField.d.ts +2 -0
  38. package/package.json +1 -1
@@ -5,7 +5,7 @@ import {
5
5
  alias,
6
6
  create,
7
7
  exists
8
- } from "../chunks/chunk-TY7XOXM3.js";
8
+ } from "../chunks/chunk-CYNFUAZ7.js";
9
9
  import {
10
10
  Expr
11
11
  } from "../chunks/chunk-4JLFL6LD.js";
@@ -17,6 +17,7 @@ import {
17
17
  PageSeed,
18
18
  Root,
19
19
  Schema,
20
+ Type,
20
21
  Workspace,
21
22
  createId,
22
23
  unreachable
@@ -438,7 +439,7 @@ ${JSON.stringify(mutation)}`
438
439
  ...data,
439
440
  path: pathData
440
441
  };
441
- const searchableText = "";
442
+ const searchableText = Type.searchableText(type, entryData);
442
443
  return {
443
444
  workspace: meta.workspace,
444
445
  root: meta.root,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  connect
3
- } from "../chunks/chunk-VRXHB6DJ.js";
3
+ } from "../chunks/chunk-LMUDRU2U.js";
4
4
  import "../chunks/chunk-FLZ4KUMA.js";
5
5
  import "../chunks/chunk-4JLFL6LD.js";
6
6
  import "../chunks/chunk-U5RRZUYZ.js";
@@ -1,9 +1,10 @@
1
1
  import {
2
+ bm25,
2
3
  count,
3
4
  iif,
4
5
  match,
5
6
  withRecursive
6
- } from "../../chunks/chunk-TY7XOXM3.js";
7
+ } from "../../chunks/chunk-CYNFUAZ7.js";
7
8
  import {
8
9
  BinOpType,
9
10
  Expr,
@@ -365,7 +366,9 @@ var EntryResolver = class {
365
366
  extra.singleResult = true;
366
367
  if (groupBy)
367
368
  extra.groupBy = groupBy.map((expr) => this.expr(ctx, expr));
368
- if (orderBy)
369
+ if (searchTerms)
370
+ extra.orderBy = [bm25(EntrySearch, 20, 1).asc()];
371
+ else if (orderBy)
369
372
  extra.orderBy = this.orderBy(ctx, orderBy);
370
373
  return query[Query.Data].with(extra);
371
374
  }
@@ -36,6 +36,7 @@ var {
36
36
  iif,
37
37
  exists,
38
38
  match,
39
+ bm25,
39
40
  highlight,
40
41
  snippet,
41
42
  cast,
@@ -112,5 +113,6 @@ export {
112
113
  count,
113
114
  iif,
114
115
  exists,
115
- match
116
+ match,
117
+ bm25
116
118
  };
@@ -2,7 +2,7 @@
2
2
  var package_default = {
3
3
  bin: "./dist/cli.js",
4
4
  name: "alinea",
5
- version: "0.5.5",
5
+ version: "0.5.6",
6
6
  license: "MIT",
7
7
  type: "module",
8
8
  scripts: {
@@ -335,8 +335,8 @@ var AsyncDriver = class extends DriverBase {
335
335
  }
336
336
  }
337
337
  async transaction(run) {
338
- const id = `t${this.transactionId++}`;
339
338
  const [connection, release] = await this.isolate();
339
+ const id = `t${this.transactionId++}`;
340
340
  await connection.executeQuery(
341
341
  new QueryData.Transaction({ op: QueryData.TransactionOperation.Begin, id })
342
342
  );
@@ -1353,6 +1353,7 @@ var SqliteFormatter = class extends Formatter {
1353
1353
  stmt.raw(" MATCH ");
1354
1354
  this.formatExprValue(ctx, query);
1355
1355
  return stmt;
1356
+ case "bm25":
1356
1357
  case "highlight":
1357
1358
  case "snippet":
1358
1359
  stmt.identifier(expr.method);
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  SqlJsDriver,
3
3
  connect
4
- } from "./chunk-VRXHB6DJ.js";
4
+ } from "./chunk-LMUDRU2U.js";
5
5
  import "./chunk-FLZ4KUMA.js";
6
6
  import "./chunk-4JLFL6LD.js";
7
7
  import "./chunk-U5RRZUYZ.js";
@@ -27,7 +27,7 @@ function generatePackage(context, config) {
27
27
  async function createDb() {
28
28
  const { default: sqlite } = await import("@alinea/sqlite-wasm");
29
29
  const { Database } = await sqlite();
30
- const { connect } = await import("../chunks/sql.js-75HGQX6U.js");
30
+ const { connect } = await import("../chunks/sql.js-RSY2XONK.js");
31
31
  const db = new Database();
32
32
  const store = connect(db).toAsync();
33
33
  return [store, () => db.export()];
package/dist/cli/Serve.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "../chunks/chunk-ULWFKWBM.js";
3
+ } from "../chunks/chunk-HWXESJ6U.js";
4
4
  import "../chunks/chunk-U5RRZUYZ.js";
5
5
 
6
6
  // src/cli/Serve.ts
package/dist/cli/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "../chunks/chunk-ULWFKWBM.js";
3
+ } from "../chunks/chunk-HWXESJ6U.js";
4
4
  import "../chunks/chunk-U5RRZUYZ.js";
5
5
 
6
6
  // node_modules/mri/lib/index.mjs
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "../../chunks/chunk-ULWFKWBM.js";
3
+ } from "../../chunks/chunk-HWXESJ6U.js";
4
4
  import {
5
5
  __commonJS,
6
6
  __toESM
@@ -3,7 +3,7 @@ import {
3
3
  } from "../../chunks/chunk-IKINPSS5.js";
4
4
  import {
5
5
  package_default
6
- } from "../../chunks/chunk-ULWFKWBM.js";
6
+ } from "../../chunks/chunk-HWXESJ6U.js";
7
7
  import "../../chunks/chunk-U5RRZUYZ.js";
8
8
 
9
9
  // src/cloud/server/CloudAuthServer.ts
@@ -2,5 +2,6 @@ import { table } from 'rado';
2
2
  export declare const EntrySearch: import("rado").Table<{
3
3
  title: import("rado").ValueColumn<string>;
4
4
  searchableText: import("rado").ValueColumn<string>;
5
+ rank: import("rado").ValueColumn<number>;
5
6
  }>;
6
7
  export type EntrySearch = table<typeof EntrySearch>;
@@ -9,6 +9,7 @@ var EntrySearch = table({
9
9
  EntrySearch: class {
10
10
  title = column.string;
11
11
  searchableText = column.string;
12
+ rank = column.number;
12
13
  }
13
14
  });
14
15
  export {
@@ -12,7 +12,7 @@ export interface Shape<Value = any, Mutator = any> {
12
12
  init(parent: YType, key: string): void;
13
13
  watch(parent: YType, key: string): (fun: () => void) => () => void;
14
14
  mutator(parent: YType, key: string, readOnly: boolean): Mutator;
15
- toString(): string;
16
15
  applyLinks(value: Value, loader: LinkResolver): Promise<void>;
16
+ searchableText(value: Value): string;
17
17
  }
18
18
  export {};
@@ -64,6 +64,7 @@ export declare namespace Type {
64
64
  function label(type: Type): Label;
65
65
  function meta(type: Type): TypeMeta;
66
66
  function shape(type: Type): RecordShape;
67
+ function searchableText(type: Type, value: any): string;
67
68
  function fields(type: Type): Record<string, Field>;
68
69
  function hint(type: Type): Hint;
69
70
  function sections(type: Type): Section[];
package/dist/core/Type.js CHANGED
@@ -34,6 +34,10 @@ var Type;
34
34
  return type2[Type2.Data].shape;
35
35
  }
36
36
  Type2.shape = shape;
37
+ function searchableText(type2, value) {
38
+ return shape(type2).searchableText(value).trim();
39
+ }
40
+ Type2.searchableText = searchableText;
37
41
  function fields(type2) {
38
42
  return type2;
39
43
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  connect
3
- } from "../../chunks/chunk-VRXHB6DJ.js";
3
+ } from "../../chunks/chunk-LMUDRU2U.js";
4
4
  import "../../chunks/chunk-FLZ4KUMA.js";
5
5
  import "../../chunks/chunk-4JLFL6LD.js";
6
6
  import "../../chunks/chunk-U5RRZUYZ.js";
@@ -2,7 +2,9 @@ import { RichTextMutator } from 'alinea/core';
2
2
  import { Field, FieldMeta, FieldOptions } from '../Field.js';
3
3
  import { TextDoc } from '../TextDoc.js';
4
4
  import { RecordShape } from '../shape/RecordShape.js';
5
- export declare class RichTextField<Blocks, Options extends FieldOptions<TextDoc<Blocks>>> extends Field<TextDoc<Blocks>, RichTextMutator<Blocks>, Options> {
5
+ export declare class RichTextField<Blocks, Options extends FieldOptions<TextDoc<Blocks>> & {
6
+ searchable?: boolean;
7
+ }> extends Field<TextDoc<Blocks>, RichTextMutator<Blocks>, Options> {
6
8
  constructor(shape: {
7
9
  [key: string]: RecordShape<any>;
8
10
  } | undefined, meta: FieldMeta<TextDoc<Blocks>, RichTextMutator<Blocks>, Options>);
@@ -9,7 +9,8 @@ var RichTextField = class extends Field {
9
9
  shape: new RichTextShape(
10
10
  meta.options.label,
11
11
  shape,
12
- meta.options.initialValue
12
+ meta.options.initialValue,
13
+ meta.options.searchable
13
14
  ),
14
15
  ...meta
15
16
  });
@@ -1,4 +1,6 @@
1
1
  import { Field, FieldMeta, FieldOptions } from '../Field.js';
2
- export declare class ScalarField<Value, Options extends FieldOptions<Value>> extends Field<Value, (value: Value) => void, Options> {
2
+ export declare class ScalarField<Value, Options extends FieldOptions<Value> & {
3
+ searchable?: boolean;
4
+ }> extends Field<Value, (value: Value) => void, Options> {
3
5
  constructor(meta: FieldMeta<Value, (value: Value) => void, Options>);
4
6
  }
@@ -6,7 +6,11 @@ import { ScalarShape } from "../shape/ScalarShape.js";
6
6
  var ScalarField = class extends Field {
7
7
  constructor(meta) {
8
8
  super({
9
- shape: new ScalarShape(meta.options.label, meta.options.initialValue),
9
+ shape: new ScalarShape(
10
+ meta.options.label,
11
+ meta.options.initialValue,
12
+ meta.options.searchable
13
+ ),
10
14
  ...meta
11
15
  });
12
16
  }
@@ -36,4 +36,5 @@ export declare class ListShape<T extends ListRow> implements Shape<Array<T>, Lis
36
36
  move: (oldIndex: number, newIndex: number) => void;
37
37
  };
38
38
  applyLinks(value: Array<T>, loader: LinkResolver): Promise<void>;
39
+ searchableText(value: Array<T>): string;
39
40
  }
@@ -206,6 +206,19 @@ var ListShape = class {
206
206
  if (this.postProcess)
207
207
  await this.postProcess(value, loader);
208
208
  }
209
+ searchableText(value) {
210
+ let res = "";
211
+ const rows = Array.isArray(value) ? value : [];
212
+ for (const row of rows) {
213
+ const id = row.id;
214
+ const type = row.type;
215
+ const shape = this.values[type];
216
+ if (!id || !type || !shape)
217
+ continue;
218
+ res += shape.searchableText(row);
219
+ }
220
+ return res;
221
+ }
209
222
  };
210
223
  export {
211
224
  ListShape
@@ -21,4 +21,5 @@ export declare class RecordShape<T = object> implements Shape<T, RecordMutator<T
21
21
  set: <K extends keyof T>(k: K, v: T[K]) => void;
22
22
  };
23
23
  applyLinks(value: T, loader: LinkResolver): Promise<void>;
24
+ searchableText(value: T): string;
24
25
  }
@@ -81,6 +81,14 @@ var RecordShape = class _RecordShape {
81
81
  }
82
82
  await Promise.all(tasks);
83
83
  }
84
+ searchableText(value) {
85
+ let res = "";
86
+ const self = value || {};
87
+ for (const key of keys(this.properties)) {
88
+ res += this.properties[key].searchableText(self[key]);
89
+ }
90
+ return res;
91
+ }
84
92
  };
85
93
  export {
86
94
  RecordShape
@@ -2,7 +2,7 @@ import { LinkResolver } from 'alinea/backend/resolver/LinkResolver';
2
2
  import * as Y from 'yjs';
3
3
  import { Label } from '../Label.js';
4
4
  import { Shape } from '../Shape.js';
5
- import { TextDoc } from '../TextDoc.js';
5
+ import { TextDoc, TextNode } from '../TextDoc.js';
6
6
  import { RecordShape } from './RecordShape.js';
7
7
  export type RichTextMutator<R> = {
8
8
  readOnly: boolean;
@@ -25,8 +25,9 @@ export declare class RichTextShape<Blocks> implements Shape<TextDoc<Blocks>, Ric
25
25
  label: Label;
26
26
  shapes?: Record<string, RecordShape<object>> | undefined;
27
27
  initialValue?: TextDoc<Blocks> | undefined;
28
+ searchable?: boolean | undefined;
28
29
  values: Record<string, RecordShape>;
29
- constructor(label: Label, shapes?: Record<string, RecordShape<object>> | undefined, initialValue?: TextDoc<Blocks> | undefined);
30
+ constructor(label: Label, shapes?: Record<string, RecordShape<object>> | undefined, initialValue?: TextDoc<Blocks> | undefined, searchable?: boolean | undefined);
30
31
  create(): TextDoc<Blocks>;
31
32
  toXml(rows: TextDoc<Blocks>): (Y.XmlElement<{
32
33
  [key: string]: string;
@@ -43,4 +44,6 @@ export declare class RichTextShape<Blocks> implements Shape<TextDoc<Blocks>, Ric
43
44
  insert: (id: string, block: string) => void;
44
45
  };
45
46
  applyLinks(doc: TextDoc<Blocks>, loader: LinkResolver): Promise<void>;
47
+ searchableText(value: TextDoc<Blocks>): string;
48
+ textOf(node: TextNode<any>): string;
46
49
  }
@@ -76,10 +76,11 @@ function unserialize(node) {
76
76
  }
77
77
  var linkInfoFields = void 0;
78
78
  var RichTextShape = class {
79
- constructor(label, shapes, initialValue) {
79
+ constructor(label, shapes, initialValue, searchable) {
80
80
  this.label = label;
81
81
  this.shapes = shapes;
82
82
  this.initialValue = initialValue;
83
+ this.searchable = searchable;
83
84
  this.values = shapes ? fromEntries(
84
85
  entries(shapes).map(([key, value]) => {
85
86
  return [
@@ -298,6 +299,30 @@ var RichTextShape = class {
298
299
  )
299
300
  );
300
301
  }
302
+ searchableText(value) {
303
+ let res = "";
304
+ if (!this.searchable)
305
+ return res;
306
+ if (!Array.isArray(value))
307
+ return res;
308
+ return value.reduce((acc, node) => {
309
+ return acc + this.textOf(node);
310
+ }, "");
311
+ }
312
+ textOf(node) {
313
+ if (this.values[node.type]) {
314
+ const shape = this.values[node.type];
315
+ return shape.searchableText(node);
316
+ }
317
+ if (node.type === "text")
318
+ return " " + node.text;
319
+ if ("content" in node && Array.isArray(node.content)) {
320
+ return node.content.reduce((acc, node2) => {
321
+ return acc + this.textOf(node2);
322
+ }, "");
323
+ }
324
+ return "";
325
+ }
301
326
  };
302
327
  function iterMarks(doc, fn) {
303
328
  for (const row of doc) {
@@ -5,7 +5,8 @@ export type ScalarMutator<T> = (value: T) => void;
5
5
  export declare class ScalarShape<T> implements Shape<T, ScalarMutator<T>> {
6
6
  label: Label;
7
7
  initialValue?: T | undefined;
8
- constructor(label: Label, initialValue?: T | undefined);
8
+ searchable?: boolean | undefined;
9
+ constructor(label: Label, initialValue?: T | undefined, searchable?: boolean | undefined);
9
10
  create(): T;
10
11
  toY(value: T): T;
11
12
  fromY(yValue: any): any;
@@ -14,4 +15,5 @@ export declare class ScalarShape<T> implements Shape<T, ScalarMutator<T>> {
14
15
  watch(parent: Y.Map<any>, key: string): (fun: () => void) => () => void;
15
16
  mutator(parent: Y.Map<any>, key: string, readOnly?: boolean): (value: T) => void;
16
17
  applyLinks(): Promise<void>;
18
+ searchableText(value: T): string;
17
19
  }
@@ -2,9 +2,10 @@ import "../../chunks/chunk-U5RRZUYZ.js";
2
2
 
3
3
  // src/core/shape/ScalarShape.ts
4
4
  var ScalarShape = class {
5
- constructor(label, initialValue) {
5
+ constructor(label, initialValue, searchable) {
6
6
  this.label = label;
7
7
  this.initialValue = initialValue;
8
+ this.searchable = searchable;
8
9
  }
9
10
  create() {
10
11
  return this.initialValue;
@@ -43,6 +44,12 @@ var ScalarShape = class {
43
44
  }
44
45
  async applyLinks() {
45
46
  }
47
+ searchableText(value) {
48
+ if (!this.searchable)
49
+ return "";
50
+ const stringified = String(value ?? "");
51
+ return stringified ? " " + stringified : "";
52
+ }
46
53
  };
47
54
  export {
48
55
  ScalarShape
@@ -26,4 +26,5 @@ export declare class UnionShape<T extends UnionRow> implements Shape<T, UnionMut
26
26
  watch(parent: Y.Map<any>, key: string): (fun: () => void) => () => void;
27
27
  mutator(parent: Y.Map<any>, key: string, readOnly: boolean): UnionMutator<T>;
28
28
  applyLinks(value: T, loader: LinkResolver): Promise<void>;
29
+ searchableText(value: T): string;
29
30
  }
@@ -122,6 +122,22 @@ var UnionShape = class {
122
122
  if (this.postProcess)
123
123
  await this.postProcess(value, loader);
124
124
  }
125
+ searchableText(value) {
126
+ let res = "";
127
+ if (Array.isArray(value))
128
+ value = value[0] ?? {};
129
+ else
130
+ value = value ?? {};
131
+ const type = value.type;
132
+ const shape = this.shapes[type];
133
+ const self = value || {};
134
+ if (!shape)
135
+ return "";
136
+ for (const [key, field] of entries(shape.properties)) {
137
+ res += field.searchableText(self[key]);
138
+ }
139
+ return res;
140
+ }
125
141
  };
126
142
  export {
127
143
  UnionShape
@@ -8,12 +8,15 @@ import { entryFilepath, entryInfo, entryUrl } from "../EntryFilenames.js";
8
8
  import { createRecord } from "../EntryRecord.js";
9
9
  import { EntryPhase } from "../EntryRow.js";
10
10
  import { Root } from "../Root.js";
11
+ import { Type } from "../Type.js";
11
12
  async function createEntryRow(config, input) {
12
13
  const record = createRecord(input);
13
14
  const fileContents = JsonLoader.format(config.schema, record);
14
15
  const fileHash = await createFileHash(fileContents);
15
16
  const rowHash = await createRowHash({ ...input, fileHash });
16
- return { ...input, fileHash, rowHash };
17
+ const type = config.schema[input.type];
18
+ const searchableText = Type.searchableText(type, input.data);
19
+ return { ...input, searchableText, fileHash, rowHash };
17
20
  }
18
21
  function entryParentPaths(config, entry) {
19
22
  const root = Root.data(config.workspaces[entry.workspace][entry.root]);
@@ -3,7 +3,7 @@ import {
3
3
  } from "../../chunks/chunk-7YXWNKGS.js";
4
4
  import {
5
5
  connect
6
- } from "../../chunks/chunk-VRXHB6DJ.js";
6
+ } from "../../chunks/chunk-LMUDRU2U.js";
7
7
  import "../../chunks/chunk-FLZ4KUMA.js";
8
8
  import {
9
9
  create,
@@ -12,12 +12,8 @@ export interface RichTextOptions<Blocks extends Schema> extends FieldOptions<Tex
12
12
  optional?: boolean;
13
13
  /** Display a minimal version */
14
14
  inline?: boolean;
15
- /** A default value */
16
- initialValue?: TextDoc<Blocks>;
17
- /** Hide this rich text field */
18
- hidden?: boolean;
19
- /** Make this rich text field read-only */
20
- readOnly?: boolean;
15
+ /** Index the text value of this field */
16
+ searchable?: boolean;
21
17
  }
22
18
  /** Create a rich text field configuration */
23
19
  export declare function richText<Blocks extends Schema = {}>(label: string, options?: WithoutLabel<RichTextOptions<Blocks>>): RichTextField<Blocks, RichTextOptions<Blocks>>;
@@ -19,6 +19,8 @@ export interface TextOptions extends FieldOptions<string> {
19
19
  iconRight?: ComponentType;
20
20
  /** Focus this input automatically */
21
21
  autoFocus?: boolean;
22
+ /** Index the text value of this field */
23
+ searchable?: boolean;
22
24
  }
23
25
  export declare class TextField extends ScalarField<string, TextOptions> {
24
26
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "bin": "./dist/cli.js",
3
3
  "name": "alinea",
4
- "version": "0.5.5",
4
+ "version": "0.5.6",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
7
  "scripts": {