@dxos/echo 0.8.4-main.03d5cd7b56 → 0.8.4-main.05e74ebcff

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 (95) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/Database.mjs +1 -1
  4. package/dist/lib/neutral/Entity.mjs +6 -6
  5. package/dist/lib/neutral/Feed.mjs +14 -12
  6. package/dist/lib/neutral/Filter.mjs +9 -7
  7. package/dist/lib/neutral/JsonSchema.mjs +4 -4
  8. package/dist/lib/neutral/Migration.mjs +6 -6
  9. package/dist/lib/neutral/Obj.mjs +8 -8
  10. package/dist/lib/neutral/Query.mjs +12 -12
  11. package/dist/lib/neutral/Ref.mjs +6 -4
  12. package/dist/lib/neutral/Relation.mjs +9 -9
  13. package/dist/lib/neutral/Tag.mjs +10 -10
  14. package/dist/lib/neutral/Type.mjs +6 -6
  15. package/dist/lib/neutral/{chunk-6VIJV543.mjs → chunk-APHSOTIX.mjs} +2 -2
  16. package/dist/lib/neutral/{chunk-RF7ZBZ4A.mjs → chunk-APJKDGFL.mjs} +16 -5
  17. package/dist/lib/neutral/chunk-APJKDGFL.mjs.map +7 -0
  18. package/dist/lib/neutral/{chunk-MPAI2MHO.mjs → chunk-BMB7IHGB.mjs} +2 -2
  19. package/dist/lib/neutral/{chunk-SUZMWP3Y.mjs → chunk-FIWO2FZK.mjs} +1 -1
  20. package/dist/lib/neutral/chunk-FIWO2FZK.mjs.map +7 -0
  21. package/dist/lib/neutral/{chunk-SJKBWMJY.mjs → chunk-G54OX4IX.mjs} +34 -18
  22. package/dist/lib/neutral/chunk-G54OX4IX.mjs.map +7 -0
  23. package/dist/lib/neutral/{chunk-FHYIM4RD.mjs → chunk-I2DARWPX.mjs} +1 -1
  24. package/dist/lib/neutral/chunk-I2DARWPX.mjs.map +7 -0
  25. package/dist/lib/neutral/{chunk-SW5CUSBY.mjs → chunk-J54QMAKF.mjs} +5 -4
  26. package/dist/lib/neutral/{chunk-SW5CUSBY.mjs.map → chunk-J54QMAKF.mjs.map} +3 -3
  27. package/dist/lib/neutral/{chunk-QXIANHKU.mjs → chunk-MGSQGHOD.mjs} +8 -8
  28. package/dist/lib/neutral/chunk-MGSQGHOD.mjs.map +7 -0
  29. package/dist/lib/neutral/{chunk-O5LRY6CO.mjs → chunk-MLS7U7AT.mjs} +2 -2
  30. package/dist/lib/neutral/{chunk-VYAGNFSJ.mjs → chunk-N7VOEPSV.mjs} +6 -3
  31. package/dist/lib/neutral/{chunk-VYAGNFSJ.mjs.map → chunk-N7VOEPSV.mjs.map} +3 -3
  32. package/dist/lib/neutral/{chunk-FZHVQEHN.mjs → chunk-PSZBLH53.mjs} +2 -2
  33. package/dist/lib/neutral/{chunk-WRVRDZDA.mjs → chunk-PT37DG2F.mjs} +4 -4
  34. package/dist/lib/neutral/{chunk-HPNQTEEQ.mjs → chunk-Q2KKKJSV.mjs} +3 -3
  35. package/dist/lib/neutral/{chunk-VGKLHHRT.mjs → chunk-Q7ZL2P5H.mjs} +18 -16
  36. package/dist/lib/neutral/{chunk-VGKLHHRT.mjs.map → chunk-Q7ZL2P5H.mjs.map} +3 -3
  37. package/dist/lib/neutral/{chunk-QGMIH2SN.mjs → chunk-QRZ2I3ZM.mjs} +2 -2
  38. package/dist/lib/neutral/{chunk-LVGOVFDV.mjs → chunk-SCPFDS2E.mjs} +2 -2
  39. package/dist/lib/neutral/{chunk-S7IMFVTB.mjs → chunk-ZFACXBY6.mjs} +19 -15
  40. package/dist/lib/neutral/chunk-ZFACXBY6.mjs.map +7 -0
  41. package/dist/lib/neutral/index.mjs +17 -17
  42. package/dist/lib/neutral/internal/index.mjs +5 -5
  43. package/dist/lib/neutral/meta.json +1 -1
  44. package/dist/lib/neutral/testing/index.mjs +17 -17
  45. package/dist/types/src/Database.d.ts +1 -1
  46. package/dist/types/src/Feed.d.ts +36 -12
  47. package/dist/types/src/Feed.d.ts.map +1 -1
  48. package/dist/types/src/Filter.d.ts +21 -0
  49. package/dist/types/src/Filter.d.ts.map +1 -1
  50. package/dist/types/src/Hypergraph.d.ts +3 -3
  51. package/dist/types/src/Hypergraph.d.ts.map +1 -1
  52. package/dist/types/src/Migration.d.ts +15 -3
  53. package/dist/types/src/Migration.d.ts.map +1 -1
  54. package/dist/types/src/Obj.d.ts +1 -1
  55. package/dist/types/src/Obj.d.ts.map +1 -1
  56. package/dist/types/src/Query.d.ts.map +1 -1
  57. package/dist/types/src/Ref.d.ts +1 -0
  58. package/dist/types/src/Ref.d.ts.map +1 -1
  59. package/dist/types/src/internal/Entity/model.d.ts +2 -0
  60. package/dist/types/src/internal/Entity/model.d.ts.map +1 -1
  61. package/dist/types/src/internal/Obj/ids.d.ts +1 -1
  62. package/dist/types/src/internal/Query.d.ts.map +1 -1
  63. package/dist/types/src/internal/common/types/meta.d.ts +10 -0
  64. package/dist/types/src/internal/common/types/meta.d.ts.map +1 -1
  65. package/dist/types/tsconfig.tsbuildinfo +1 -1
  66. package/package.json +14 -14
  67. package/src/Database.ts +1 -1
  68. package/src/Feed.ts +55 -24
  69. package/src/Filter.ts +31 -0
  70. package/src/Hypergraph.ts +3 -3
  71. package/src/Migration.ts +19 -7
  72. package/src/Obj.ts +1 -0
  73. package/src/Query.test.ts +16 -16
  74. package/src/Query.ts +12 -7
  75. package/src/Ref.ts +2 -0
  76. package/src/internal/Entity/model.ts +2 -0
  77. package/src/internal/Obj/ids.ts +1 -1
  78. package/src/internal/Obj/json-serializer.ts +9 -9
  79. package/src/internal/Query.ts +23 -4
  80. package/src/internal/common/proxy/reactive.test.ts +1 -1
  81. package/src/internal/common/types/meta.ts +12 -0
  82. package/dist/lib/neutral/chunk-FHYIM4RD.mjs.map +0 -7
  83. package/dist/lib/neutral/chunk-QXIANHKU.mjs.map +0 -7
  84. package/dist/lib/neutral/chunk-RF7ZBZ4A.mjs.map +0 -7
  85. package/dist/lib/neutral/chunk-S7IMFVTB.mjs.map +0 -7
  86. package/dist/lib/neutral/chunk-SJKBWMJY.mjs.map +0 -7
  87. package/dist/lib/neutral/chunk-SUZMWP3Y.mjs.map +0 -7
  88. /package/dist/lib/neutral/{chunk-6VIJV543.mjs.map → chunk-APHSOTIX.mjs.map} +0 -0
  89. /package/dist/lib/neutral/{chunk-MPAI2MHO.mjs.map → chunk-BMB7IHGB.mjs.map} +0 -0
  90. /package/dist/lib/neutral/{chunk-O5LRY6CO.mjs.map → chunk-MLS7U7AT.mjs.map} +0 -0
  91. /package/dist/lib/neutral/{chunk-FZHVQEHN.mjs.map → chunk-PSZBLH53.mjs.map} +0 -0
  92. /package/dist/lib/neutral/{chunk-WRVRDZDA.mjs.map → chunk-PT37DG2F.mjs.map} +0 -0
  93. /package/dist/lib/neutral/{chunk-HPNQTEEQ.mjs.map → chunk-Q2KKKJSV.mjs.map} +0 -0
  94. /package/dist/lib/neutral/{chunk-QGMIH2SN.mjs.map → chunk-QRZ2I3ZM.mjs.map} +0 -0
  95. /package/dist/lib/neutral/{chunk-LVGOVFDV.mjs.map → chunk-SCPFDS2E.mjs.map} +0 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/Query.ts"],
4
- "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as EffectArray from 'effect/Array';\nimport type * as Schema from 'effect/Schema';\n\nimport { type QueryAST } from '@dxos/echo-protocol';\n\nimport type * as Collection from './Collection';\nimport * as Database from './Database';\nimport type * as Dataset from './Dataset';\nimport * as Feed from './Feed';\nimport * as Filter from './Filter';\nimport * as internal from './internal';\nimport * as Obj from './Obj';\nimport type * as Order from './Order';\nimport type * as Ref from './Ref';\nimport type * as Relation from './Relation';\nimport type * as View from './View';\n\n// TODO(dmaretskyi): Split up into interfaces for objects and relations so they can have separate verbs.\n// TODO(dmaretskyi): Undirected relation traversals.\n// TODO(wittjosiah): Make Filter & Query pipeable.\n\n/**\n * All property paths inside T that are references.\n */\n// TODO(dmaretskyi): Filter only properties that are references (or optional references, or unions that include references).\ntype RefPropKey<T> = keyof T & string;\n\n// TODO(burdon): Narrow T to Entity.Unknown?\nexport interface Query<T> {\n // TODO(dmaretskyi): See new effect-schema approach to variance.\n '~Query': { value: T };\n\n ast: QueryAST.Query;\n\n /**\n * Filter the current selection based on a filter.\n * @param filter - Filter to select the objects.\n * @returns Query for the selected objects.\n */\n 'select'(filter: Filter.Filter<T>): Query<T>;\n 'select'(props: Filter.Props<T>): Query<T>;\n\n /**\n * Traverse an outgoing reference.\n * @param key - Property path inside T that is a reference or optional reference.\n * @returns Query for the target of the reference.\n */\n 'reference'<K extends RefPropKey<T>>(\n key: K,\n ): Query<\n T[K] extends Ref.Unknown\n ? Ref.Target<T[K]>\n : T[K] extends Ref.Unknown | undefined\n ? Ref.Target<Exclude<T[K], undefined>>\n : never\n >;\n\n /**\n * Find objects referencing this object.\n * @param target - Schema of the referencing object. If not provided, matches any type.\n * @param key - Property path inside the referencing object that is a reference. If not provided, matches any property.\n * @returns Query for the referencing objects.\n */\n // TODO(dmaretskyi): any way to enforce `Ref.Target<Schema.Schema.Type<S>[key]> == T`?\n // TODO(dmaretskyi): Ability to go through arrays of references.\n 'referencedBy'<S extends Schema.Schema.All>(\n target: S | string,\n key: RefPropKey<Schema.Schema.Type<S>>,\n ): Query<Schema.Schema.Type<S>>;\n 'referencedBy'<S extends Schema.Schema.All>(target: S | string): Query<Schema.Schema.Type<S>>;\n 'referencedBy'(): Query<any>;\n\n /**\n * Find relations where this object is the source.\n * @returns Query for the relation objects.\n * @param relation - Schema of the relation.\n * @param predicates - Predicates to filter the relation objects.\n */\n 'sourceOf'<S extends Schema.Schema.All>(\n relation?: S | string,\n predicates?: Filter.Props<Schema.Schema.Type<S>>,\n ): Query<Schema.Schema.Type<S>>;\n\n /**\n * Find relations where this object is the target.\n * @returns Query for the relation objects.\n * @param relation - Schema of the relation.\n * @param predicates - Predicates to filter the relation objects.\n */\n 'targetOf'<S extends Schema.Schema.All>(\n relation?: S | string,\n predicates?: Filter.Props<Schema.Schema.Type<S>>,\n ): Query<Schema.Schema.Type<S>>;\n\n /**\n * For a query for relations, get the source objects.\n * @returns Query for the source objects.\n */\n 'source'(): Query<Relation.SourceOf<T>>;\n\n /**\n * For a query for relations, get the target objects.\n * @returns Query for the target objects.\n */\n 'target'(): Query<Relation.TargetOf<T>>;\n\n /**\n * Get the parent object of the current selection.\n * @returns Query for the parent objects.\n */\n 'parent'(): Query<any>;\n\n /**\n * Get all child objects of the current selection.\n * @returns Query for the child objects.\n */\n 'children'(): Query<any>;\n\n /**\n * Order the query results.\n * Orders are specified in priority order. The first order will be applied first, etc.\n * @param order - Order to sort the results.\n * @returns Query for the ordered results.\n */\n 'orderBy'(...order: EffectArray.NonEmptyArray<Order.Order<T>>): Query<T>;\n\n /**\n * Limit the number of results.\n * @param limit - Maximum number of results to return.\n * @returns Query for the limited results.\n */\n 'limit'(limit: number): Query<T>;\n\n /**\n * Query from selected databases only.\n *\n * Example:\n *\n * ```ts\n * Query.select(Filter.type(Person)).from(db);\n * ```\n *\n * @param options.includeFeeds [false] - Whether to include feeds in the query. Default is to query from automerge documents only.\n */\n 'from'(database: Database.Database | Database.Database[], options?: { includeFeeds?: boolean }): Query<T>;\n\n /**\n * Query from selected feeds only.\n *\n * Example:\n *\n * ```ts\n * Query.select(Filter.type(Person)).from(feed);\n * ```\n *\n */\n 'from'(feeds: Feed.Feed | Feed.Feed[]): Query<T>;\n\n /**\n * Query from all accessible spaces.\n *\n * Example:\n *\n * ```ts\n * Query.select(Filter.type(Person)).from('all-accessible-spaces');\n * ```\n *\n * @param options.includeFeeds [false] - Whether to include feeds in the query. Default is to query from automerge documents only.\n */\n 'from'(allSpaces: 'all-accessible-spaces', options?: { includeFeeds?: boolean }): Query<T>;\n\n /**\n * Query from a dataset.\n * Currently only feeds are supported.\n *\n * Example:\n *\n * ```ts\n * Query.type(Person).from(feed);\n * ```\n */\n 'from'(dataset: Dataset.Dataset): Query<T>;\n\n /**\n * Query from the results of another query.\n *\n * Example:\n *\n * ```ts\n * Query.select(Filter.props({ foo: 'foo' })).from(Query.select(Filter.type(Contact)).reference('org'));\n * ```\n */\n 'from'(query: Any): Query<T>;\n\n /**\n * Query from a raw scope specification.\n */\n 'from'(scope: QueryAST.Scope): Query<T>;\n\n /**\n * Add options to a query.\n */\n 'options'(options: QueryAST.QueryOptions): Query<T>;\n\n /**\n * Attach a diagnostic label for logs and tooling (execution semantics unchanged).\n */\n 'debugLabel'(label: string): Query<T>;\n}\n\nexport type Any = Query<any>;\n\nexport type Type<Q extends Any> = Q extends Query<infer T> ? T : never;\n\nclass QueryClass implements Any {\n private static 'variance': Any['~Query'] = {} as Any['~Query'];\n\n constructor(public readonly ast: QueryAST.Query) {}\n\n '~Query' = QueryClass.variance;\n\n select(filter: Filter.Any | Filter.Props<any>): Any {\n if (Filter.is(filter)) {\n return new QueryClass({\n type: 'filter',\n selection: this.ast,\n filter: filter.ast,\n });\n } else {\n return new QueryClass({\n type: 'filter',\n selection: this.ast,\n filter: Filter.props(filter).ast,\n });\n }\n }\n\n reference(key: string): Any {\n return new QueryClass({\n type: 'reference-traversal',\n anchor: this.ast,\n property: key,\n });\n }\n\n referencedBy(target?: Schema.Schema.All | string, key?: string): Any {\n const dxn = target !== undefined ? internal.getTypeDXNFromSpecifier(target) : null;\n return new QueryClass({\n type: 'incoming-references',\n anchor: this.ast,\n property: key ?? null,\n typename: dxn?.toString() ?? null,\n });\n }\n\n sourceOf(relation?: Schema.Schema.All | string, predicates?: Filter.Props<unknown> | undefined): Any {\n return new QueryClass({\n type: 'relation',\n anchor: this.ast,\n direction: 'outgoing',\n filter: relation !== undefined ? Filter.type(relation, predicates).ast : undefined,\n });\n }\n\n targetOf(relation?: Schema.Schema.All | string, predicates?: Filter.Props<unknown> | undefined): Any {\n return new QueryClass({\n type: 'relation',\n anchor: this.ast,\n direction: 'incoming',\n filter: relation !== undefined ? Filter.type(relation, predicates).ast : undefined,\n });\n }\n\n source(): Any {\n return new QueryClass({\n type: 'relation-traversal',\n anchor: this.ast,\n direction: 'source',\n });\n }\n\n target(): Any {\n return new QueryClass({\n type: 'relation-traversal',\n anchor: this.ast,\n direction: 'target',\n });\n }\n\n parent(): Any {\n return new QueryClass({\n type: 'hierarchy-traversal',\n anchor: this.ast,\n direction: 'to-parent',\n });\n }\n\n children(): Any {\n return new QueryClass({\n type: 'hierarchy-traversal',\n anchor: this.ast,\n direction: 'to-children',\n });\n }\n\n orderBy(...order: Order.Order<any>[]): Any {\n return new QueryClass({\n type: 'order',\n query: this.ast,\n order: order.map((o) => o.ast),\n });\n }\n\n limit(limit: number): Any {\n return new QueryClass({\n type: 'limit',\n query: this.ast,\n limit,\n });\n }\n\n from(\n arg:\n | Database.Database\n | Database.Database[]\n | Feed.Feed\n | Feed.Feed[]\n | Collection.Collection\n | View.View\n | Any\n | QueryAST.Scope\n | 'all-accessible-spaces',\n options?: { includeFeeds?: boolean },\n ): Any {\n if (arg == null) {\n throw new TypeError(\n 'Query.from() requires a valid data source argument (database, feed, query, scope, or \"all-accessible-spaces\").',\n );\n }\n\n if (is(arg)) {\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: { _tag: 'query', query: arg.ast },\n });\n }\n\n if (arg === 'all-accessible-spaces') {\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: {\n _tag: 'scope',\n scope: {\n ...(options?.includeFeeds ? { allQueuesFromSpaces: true } : {}),\n },\n },\n });\n }\n\n if (_isScope(arg)) {\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: { _tag: 'scope', scope: arg },\n });\n }\n\n const items = Array.isArray(arg) ? arg : [arg];\n\n if (items.length > 0 && Database.isDatabase(items[0])) {\n const databases = items as Database.Database[];\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: {\n _tag: 'scope',\n scope: {\n spaceIds: databases.map((db) => db.spaceId),\n ...(options?.includeFeeds ? { allQueuesFromSpaces: true } : {}),\n },\n },\n });\n }\n\n if (items.length > 0) {\n const typename = Obj.getTypename(items[0] as Obj.Unknown);\n // TODO(dmaretskyi): Support querying from views.\n if (typename === 'org.dxos.type.view') {\n throw new Error('Query.from(view) is not yet supported.');\n }\n // TODO(dmaretskyi): Support querying from collections.\n if (typename === 'org.dxos.type.collection') {\n throw new Error('Query.from(collection) is not yet supported.');\n }\n // Validate that the items are Feed.Feed instances.\n for (const item of items) {\n if (!Obj.instanceOf(Feed.Feed, item)) {\n throw new TypeError(\n `Query.from() expects Feed objects (org.dxos.type.feed), but received an object with typename '${typename ?? 'unknown'}'.`,\n );\n }\n }\n }\n\n const feeds = items as Feed.Feed[];\n const queueDxns = feeds.flatMap((feed) => {\n const dxn = Feed.getQueueDxn(feed);\n return dxn ? [dxn.toString()] : [];\n });\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: {\n _tag: 'scope',\n scope: {\n queues: queueDxns,\n },\n },\n });\n }\n\n options(options: QueryAST.QueryOptions): Any {\n return new QueryClass({\n type: 'options',\n query: this.ast,\n options,\n });\n }\n\n debugLabel(label: string): Any {\n if (this.ast.type === 'options') {\n return new QueryClass({\n type: 'options',\n query: this.ast.query,\n options: { ...this.ast.options, debugLabel: label },\n });\n }\n return new QueryClass({\n type: 'options',\n query: this.ast,\n options: { debugLabel: label },\n });\n }\n}\n\nexport const is = (value: unknown): value is Any => {\n return typeof value === 'object' && value !== null && '~Query' in value;\n};\n\n/** Construct a query from an ast. */\nexport const fromAst = (ast: QueryAST.Query): Any => {\n return new QueryClass(ast);\n};\n\n/**\n * Select objects based on a filter.\n * @param filter - Filter to select the objects.\n * @returns Query for the selected objects.\n */\nexport const select = <F extends Filter.Any>(filter: F): Query<Filter.Type<F>> => {\n return new QueryClass({\n type: 'select',\n filter: filter.ast,\n });\n};\n\n/**\n * Query for objects of a given schema.\n * @param schema - Schema of the objects.\n * @param predicates - Predicates to filter the objects.\n * @returns Query for the objects.\n *\n * Shorthand for: `Query.select(Filter.type(schema, predicates))`.\n */\nexport const type: {\n <S extends Schema.Schema.All>(\n schema: S,\n predicates?: Filter.Props<Schema.Schema.Type<S>>,\n ): Query<Schema.Schema.Type<S>>;\n (schema: string, predicates?: Filter.Props<unknown>): Query<any>;\n} = (schema: Schema.Schema.All | string, predicates?: Filter.Props<unknown>): Any => {\n return new QueryClass({\n type: 'select',\n filter: Filter.type(schema, predicates).ast,\n });\n};\n\n/**\n * Combine results of multiple queries.\n * @param queries - Queries to combine.\n * @returns Query for the combined results.\n */\n// TODO(dmaretskyi): Rename to `combine` or `union`.\nexport const all = (...queries: Any[]): Any => {\n if (queries.length === 0) {\n throw new TypeError(\n 'Query.all combines results of multiple queries, to query all objects use Query.select(Filter.everything())',\n );\n }\n return new QueryClass({\n type: 'union',\n queries: queries.map((q) => q.ast),\n });\n};\n\n/**\n * Subtract one query from another.\n * @param source - Query to subtract from.\n * @param exclude - Query to subtract.\n * @returns Query for the results of the source query minus the results of the exclude query.\n */\nexport const without = <T>(source: Query<T>, exclude: Query<T>): Query<T> => {\n return new QueryClass({\n type: 'set-difference',\n source: source.ast,\n exclude: exclude.ast,\n });\n};\n\n/**\n * Create a query scoped to a data source.\n * The returned query selects everything from the source; chain `.select()` to narrow results.\n *\n * @param source - Data source: database, feed, 'all-accessible-spaces', or another query.\n * @returns Query scoped to the given source.\n */\nexport const from = (\n source:\n | Database.Database\n | Database.Database[]\n | Feed.Feed\n | Feed.Feed[]\n | Any\n | QueryAST.Scope\n | 'all-accessible-spaces',\n options?: { includeFeeds?: boolean },\n): Any => {\n const baseQuery: QueryAST.Query = {\n type: 'select',\n filter: Filter.everything().ast,\n };\n const wrapper = new QueryClass(baseQuery);\n return wrapper.from(source as any, options);\n};\n\nconst SCOPE_KEYS = new Set(['spaceIds', 'queues', 'allQueuesFromSpaces']);\n\n/** Detect a raw Scope object (plain object with only Scope-valid keys). */\nconst _isScope = (value: unknown): value is QueryAST.Scope => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n return Object.keys(value).every((key) => SCOPE_KEYS.has(key));\n};\n\n/**\n * Returns a human-readable string representation of a Query AST.\n */\nexport const pretty = (query: Any): string => internal.prettyQuery(query.ast);\n"],
5
- "mappings": "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",
6
- "names": ["is", "type", "QueryClass", "ast", "variance", "select", "filter", "is", "type", "selection", "props", "reference", "key", "anchor", "property", "referencedBy", "target", "dxn", "undefined", "getTypeDXNFromSpecifier", "typename", "toString", "sourceOf", "relation", "predicates", "direction", "targetOf", "source", "parent", "children", "orderBy", "order", "query", "map", "o", "limit", "from", "arg", "options", "TypeError", "_tag", "scope", "includeFeeds", "allQueuesFromSpaces", "_isScope", "items", "Array", "isArray", "length", "isDatabase", "databases", "spaceIds", "db", "spaceId", "getTypename", "Error", "item", "instanceOf", "Feed", "feeds", "queueDxns", "flatMap", "feed", "getQueueDxn", "queues", "debugLabel", "label", "value", "fromAst", "schema", "all", "queries", "q", "without", "exclude", "baseQuery", "everything", "wrapper", "SCOPE_KEYS", "Set", "Object", "keys", "every", "has", "pretty", "prettyQuery"]
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport type * as EffectArray from 'effect/Array';\nimport type * as Schema from 'effect/Schema';\n\nimport { type QueryAST } from '@dxos/echo-protocol';\n\nimport type * as Collection from './Collection';\nimport * as Database from './Database';\nimport type * as Dataset from './Dataset';\nimport * as Feed from './Feed';\nimport * as Filter from './Filter';\nimport * as internal from './internal';\nimport * as Obj from './Obj';\nimport type * as Order from './Order';\nimport type * as Ref from './Ref';\nimport type * as Relation from './Relation';\nimport type * as View from './View';\n\n// TODO(dmaretskyi): Split up into interfaces for objects and relations so they can have separate verbs.\n// TODO(dmaretskyi): Undirected relation traversals.\n// TODO(wittjosiah): Make Filter & Query pipeable.\n\n/**\n * All property paths inside T that are references.\n */\n// TODO(dmaretskyi): Filter only properties that are references (or optional references, or unions that include references).\ntype RefPropKey<T> = keyof T & string;\n\n// TODO(burdon): Narrow T to Entity.Unknown?\nexport interface Query<T> {\n // TODO(dmaretskyi): See new effect-schema approach to variance.\n '~Query': { value: T };\n\n ast: QueryAST.Query;\n\n /**\n * Filter the current selection based on a filter.\n * @param filter - Filter to select the objects.\n * @returns Query for the selected objects.\n */\n 'select'(filter: Filter.Filter<T>): Query<T>;\n 'select'(props: Filter.Props<T>): Query<T>;\n\n /**\n * Traverse an outgoing reference.\n * @param key - Property path inside T that is a reference or optional reference.\n * @returns Query for the target of the reference.\n */\n 'reference'<K extends RefPropKey<T>>(\n key: K,\n ): Query<\n T[K] extends Ref.Unknown\n ? Ref.Target<T[K]>\n : T[K] extends Ref.Unknown | undefined\n ? Ref.Target<Exclude<T[K], undefined>>\n : never\n >;\n\n /**\n * Find objects referencing this object.\n * @param target - Schema of the referencing object. If not provided, matches any type.\n * @param key - Property path inside the referencing object that is a reference. If not provided, matches any property.\n * @returns Query for the referencing objects.\n */\n // TODO(dmaretskyi): any way to enforce `Ref.Target<Schema.Schema.Type<S>[key]> == T`?\n // TODO(dmaretskyi): Ability to go through arrays of references.\n 'referencedBy'<S extends Schema.Schema.All>(\n target: S | string,\n key: RefPropKey<Schema.Schema.Type<S>>,\n ): Query<Schema.Schema.Type<S>>;\n 'referencedBy'<S extends Schema.Schema.All>(target: S | string): Query<Schema.Schema.Type<S>>;\n 'referencedBy'(): Query<any>;\n\n /**\n * Find relations where this object is the source.\n * @returns Query for the relation objects.\n * @param relation - Schema of the relation.\n * @param predicates - Predicates to filter the relation objects.\n */\n 'sourceOf'<S extends Schema.Schema.All>(\n relation?: S | string,\n predicates?: Filter.Props<Schema.Schema.Type<S>>,\n ): Query<Schema.Schema.Type<S>>;\n\n /**\n * Find relations where this object is the target.\n * @returns Query for the relation objects.\n * @param relation - Schema of the relation.\n * @param predicates - Predicates to filter the relation objects.\n */\n 'targetOf'<S extends Schema.Schema.All>(\n relation?: S | string,\n predicates?: Filter.Props<Schema.Schema.Type<S>>,\n ): Query<Schema.Schema.Type<S>>;\n\n /**\n * For a query for relations, get the source objects.\n * @returns Query for the source objects.\n */\n 'source'(): Query<Relation.SourceOf<T>>;\n\n /**\n * For a query for relations, get the target objects.\n * @returns Query for the target objects.\n */\n 'target'(): Query<Relation.TargetOf<T>>;\n\n /**\n * Get the parent object of the current selection.\n * @returns Query for the parent objects.\n */\n 'parent'(): Query<any>;\n\n /**\n * Get all child objects of the current selection.\n * @returns Query for the child objects.\n */\n 'children'(): Query<any>;\n\n /**\n * Order the query results.\n * Orders are specified in priority order. The first order will be applied first, etc.\n * @param order - Order to sort the results.\n * @returns Query for the ordered results.\n */\n 'orderBy'(...order: EffectArray.NonEmptyArray<Order.Order<T>>): Query<T>;\n\n /**\n * Limit the number of results.\n * @param limit - Maximum number of results to return.\n * @returns Query for the limited results.\n */\n 'limit'(limit: number): Query<T>;\n\n /**\n * Query from selected databases only.\n *\n * Example:\n *\n * ```ts\n * Query.select(Filter.type(Person)).from(db);\n * ```\n *\n * @param options.includeFeeds [false] - Whether to include feeds in the query. Default is to query from automerge documents only.\n */\n 'from'(database: Database.Database | Database.Database[], options?: { includeFeeds?: boolean }): Query<T>;\n\n /**\n * Query from selected feeds only.\n *\n * Example:\n *\n * ```ts\n * Query.select(Filter.type(Person)).from(feed);\n * ```\n *\n */\n 'from'(feeds: Feed.Feed | Feed.Feed[]): Query<T>;\n\n /**\n * Query from all accessible spaces.\n *\n * Example:\n *\n * ```ts\n * Query.select(Filter.type(Person)).from('all-accessible-spaces');\n * ```\n *\n * @param options.includeFeeds [false] - Whether to include feeds in the query. Default is to query from automerge documents only.\n */\n 'from'(allSpaces: 'all-accessible-spaces', options?: { includeFeeds?: boolean }): Query<T>;\n\n /**\n * Query from a dataset.\n * Currently only feeds are supported.\n *\n * Example:\n *\n * ```ts\n * Query.type(Person).from(feed);\n * ```\n */\n 'from'(dataset: Dataset.Dataset): Query<T>;\n\n /**\n * Query from the results of another query.\n *\n * Example:\n *\n * ```ts\n * Query.select(Filter.props({ foo: 'foo' })).from(Query.select(Filter.type(Contact)).reference('org'));\n * ```\n */\n 'from'(query: Any): Query<T>;\n\n /**\n * Query from a raw scope specification.\n */\n 'from'(scope: QueryAST.Scope): Query<T>;\n\n /**\n * Add options to a query.\n */\n 'options'(options: QueryAST.QueryOptions): Query<T>;\n\n /**\n * Attach a diagnostic label for logs and tooling (execution semantics unchanged).\n */\n 'debugLabel'(label: string): Query<T>;\n}\n\nexport type Any = Query<any>;\n\nexport type Type<Q extends Any> = Q extends Query<infer T> ? T : never;\n\nclass QueryClass implements Any {\n private static 'variance': Any['~Query'] = {} as Any['~Query'];\n\n constructor(public readonly ast: QueryAST.Query) {}\n\n '~Query' = QueryClass.variance;\n\n select(filter: Filter.Any | Filter.Props<any>): Any {\n if (Filter.is(filter)) {\n return new QueryClass({\n type: 'filter',\n selection: this.ast,\n filter: filter.ast,\n });\n } else {\n return new QueryClass({\n type: 'filter',\n selection: this.ast,\n filter: Filter.props(filter).ast,\n });\n }\n }\n\n reference(key: string): Any {\n return new QueryClass({\n type: 'reference-traversal',\n anchor: this.ast,\n property: key,\n });\n }\n\n referencedBy(target?: Schema.Schema.All | string, key?: string): Any {\n const dxn = target !== undefined ? internal.getTypeDXNFromSpecifier(target) : null;\n return new QueryClass({\n type: 'incoming-references',\n anchor: this.ast,\n property: key ?? null,\n typename: dxn?.toString() ?? null,\n });\n }\n\n sourceOf(relation?: Schema.Schema.All | string, predicates?: Filter.Props<unknown> | undefined): Any {\n return new QueryClass({\n type: 'relation',\n anchor: this.ast,\n direction: 'outgoing',\n filter: relation !== undefined ? Filter.type(relation, predicates).ast : undefined,\n });\n }\n\n targetOf(relation?: Schema.Schema.All | string, predicates?: Filter.Props<unknown> | undefined): Any {\n return new QueryClass({\n type: 'relation',\n anchor: this.ast,\n direction: 'incoming',\n filter: relation !== undefined ? Filter.type(relation, predicates).ast : undefined,\n });\n }\n\n source(): Any {\n return new QueryClass({\n type: 'relation-traversal',\n anchor: this.ast,\n direction: 'source',\n });\n }\n\n target(): Any {\n return new QueryClass({\n type: 'relation-traversal',\n anchor: this.ast,\n direction: 'target',\n });\n }\n\n parent(): Any {\n return new QueryClass({\n type: 'hierarchy-traversal',\n anchor: this.ast,\n direction: 'to-parent',\n });\n }\n\n children(): Any {\n return new QueryClass({\n type: 'hierarchy-traversal',\n anchor: this.ast,\n direction: 'to-children',\n });\n }\n\n orderBy(...order: Order.Order<any>[]): Any {\n return new QueryClass({\n type: 'order',\n query: this.ast,\n order: order.map((o) => o.ast),\n });\n }\n\n limit(limit: number): Any {\n return new QueryClass({\n type: 'limit',\n query: this.ast,\n limit,\n });\n }\n\n from(\n arg:\n | Database.Database\n | Database.Database[]\n | Feed.Feed\n | Feed.Feed[]\n | Collection.Collection\n | View.View\n | Any\n | QueryAST.Scope\n | 'all-accessible-spaces',\n options?: { includeFeeds?: boolean },\n ): Any {\n if (arg == null) {\n throw new TypeError(\n 'Query.from() requires a valid data source argument (database, feed, query, scope, or \"all-accessible-spaces\").',\n );\n }\n\n if (is(arg)) {\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: { _tag: 'query', query: arg.ast },\n });\n }\n\n if (arg === 'all-accessible-spaces') {\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: {\n _tag: 'scope',\n scope: {\n ...(options?.includeFeeds ? { allFeedsFromSpaces: true } : {}),\n },\n },\n });\n }\n\n if (_isScope(arg)) {\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: { _tag: 'scope', scope: arg },\n });\n }\n\n const items = Array.isArray(arg) ? arg : [arg];\n\n if (items.length > 0 && Database.isDatabase(items[0])) {\n const databases = items as Database.Database[];\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: {\n _tag: 'scope',\n scope: {\n spaceIds: databases.map((db) => db.spaceId),\n ...(options?.includeFeeds ? { allFeedsFromSpaces: true } : {}),\n },\n },\n });\n }\n\n if (items.length > 0) {\n const typename = Obj.getTypename(items[0] as Obj.Unknown);\n // TODO(dmaretskyi): Support querying from views.\n if (typename === 'org.dxos.type.view') {\n throw new Error('Query.from(view) is not yet supported.');\n }\n // TODO(dmaretskyi): Support querying from collections.\n if (typename === 'org.dxos.type.collection') {\n throw new Error('Query.from(collection) is not yet supported.');\n }\n // Validate that the items are Feed.Feed instances.\n for (const item of items) {\n if (!Obj.instanceOf(Feed.Feed, item)) {\n throw new TypeError(\n `Query.from() expects Feed objects (org.dxos.type.feed), but received an object with typename '${typename ?? 'unknown'}'.`,\n );\n }\n }\n }\n\n const feedItems = items as Feed.Feed[];\n const feedDXNs = feedItems.map((feed) => {\n const dxn = Feed.getQueueDxn(feed);\n if (!dxn) {\n throw new TypeError(\n `Query.from() expects persisted Feed objects with a queue DXN; got feed without a space (id=${Obj.getDXN(feed).toString()}).`,\n );\n }\n return dxn.toString();\n });\n return new QueryClass({\n type: 'from',\n query: this.ast,\n from: {\n _tag: 'scope',\n scope: {\n feeds: feedDXNs,\n },\n },\n });\n }\n\n options(options: QueryAST.QueryOptions): Any {\n return new QueryClass({\n type: 'options',\n query: this.ast,\n options,\n });\n }\n\n debugLabel(label: string): Any {\n if (this.ast.type === 'options') {\n return new QueryClass({\n type: 'options',\n query: this.ast.query,\n options: { ...this.ast.options, debugLabel: label },\n });\n }\n return new QueryClass({\n type: 'options',\n query: this.ast,\n options: { debugLabel: label },\n });\n }\n}\n\nexport const is = (value: unknown): value is Any => {\n return typeof value === 'object' && value !== null && '~Query' in value;\n};\n\n/** Construct a query from an ast. */\nexport const fromAst = (ast: QueryAST.Query): Any => {\n return new QueryClass(ast);\n};\n\n/**\n * Select objects based on a filter.\n * @param filter - Filter to select the objects.\n * @returns Query for the selected objects.\n */\nexport const select = <F extends Filter.Any>(filter: F): Query<Filter.Type<F>> => {\n return new QueryClass({\n type: 'select',\n filter: filter.ast,\n });\n};\n\n/**\n * Query for objects of a given schema.\n * @param schema - Schema of the objects.\n * @param predicates - Predicates to filter the objects.\n * @returns Query for the objects.\n *\n * Shorthand for: `Query.select(Filter.type(schema, predicates))`.\n */\nexport const type: {\n <S extends Schema.Schema.All>(\n schema: S,\n predicates?: Filter.Props<Schema.Schema.Type<S>>,\n ): Query<Schema.Schema.Type<S>>;\n (schema: string, predicates?: Filter.Props<unknown>): Query<any>;\n} = (schema: Schema.Schema.All | string, predicates?: Filter.Props<unknown>): Any => {\n return new QueryClass({\n type: 'select',\n filter: Filter.type(schema, predicates).ast,\n });\n};\n\n/**\n * Combine results of multiple queries.\n * @param queries - Queries to combine.\n * @returns Query for the combined results.\n */\n// TODO(dmaretskyi): Rename to `combine` or `union`.\nexport const all = (...queries: Any[]): Any => {\n if (queries.length === 0) {\n throw new TypeError(\n 'Query.all combines results of multiple queries, to query all objects use Query.select(Filter.everything())',\n );\n }\n return new QueryClass({\n type: 'union',\n queries: queries.map((q) => q.ast),\n });\n};\n\n/**\n * Subtract one query from another.\n * @param source - Query to subtract from.\n * @param exclude - Query to subtract.\n * @returns Query for the results of the source query minus the results of the exclude query.\n */\nexport const without = <T>(source: Query<T>, exclude: Query<T>): Query<T> => {\n return new QueryClass({\n type: 'set-difference',\n source: source.ast,\n exclude: exclude.ast,\n });\n};\n\n/**\n * Create a query scoped to a data source.\n * The returned query selects everything from the source; chain `.select()` to narrow results.\n *\n * @param source - Data source: database, feed, 'all-accessible-spaces', or another query.\n * @returns Query scoped to the given source.\n */\nexport const from = (\n source:\n | Database.Database\n | Database.Database[]\n | Feed.Feed\n | Feed.Feed[]\n | Any\n | QueryAST.Scope\n | 'all-accessible-spaces',\n options?: { includeFeeds?: boolean },\n): Any => {\n const baseQuery: QueryAST.Query = {\n type: 'select',\n filter: Filter.everything().ast,\n };\n const wrapper = new QueryClass(baseQuery);\n return wrapper.from(source as any, options);\n};\n\nconst SCOPE_KEYS = new Set(['spaceIds', 'feeds', 'allFeedsFromSpaces']);\n\n/** Detect a raw Scope object (plain object with only Scope-valid keys). */\nconst _isScope = (value: unknown): value is QueryAST.Scope => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n return Object.keys(value).every((key) => SCOPE_KEYS.has(key));\n};\n\n/**\n * Returns a human-readable string representation of a Query AST.\n */\nexport const pretty = (query: Any): string => internal.prettyQuery(query.ast);\n"],
5
+ "mappings": "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",
6
+ "names": ["is", "type", "QueryClass", "ast", "variance", "select", "filter", "is", "type", "selection", "props", "reference", "key", "anchor", "property", "referencedBy", "target", "dxn", "undefined", "getTypeDXNFromSpecifier", "typename", "toString", "sourceOf", "relation", "predicates", "direction", "targetOf", "source", "parent", "children", "orderBy", "order", "query", "map", "o", "limit", "from", "arg", "options", "TypeError", "_tag", "scope", "includeFeeds", "allFeedsFromSpaces", "_isScope", "items", "Array", "isArray", "length", "isDatabase", "databases", "spaceIds", "db", "spaceId", "getTypename", "Error", "item", "instanceOf", "Feed", "feedItems", "feedDXNs", "feed", "getQueueDxn", "getDXN", "feeds", "debugLabel", "label", "value", "fromAst", "schema", "all", "queries", "q", "without", "exclude", "baseQuery", "everything", "wrapper", "SCOPE_KEYS", "Set", "Object", "keys", "every", "has", "pretty", "prettyQuery"]
7
7
  }
@@ -2,7 +2,7 @@ import {
2
2
  JsonSchemaType,
3
3
  toEffectSchema,
4
4
  toJsonSchema
5
- } from "./chunk-O5LRY6CO.mjs";
5
+ } from "./chunk-MLS7U7AT.mjs";
6
6
  import {
7
7
  __export
8
8
  } from "./chunk-J5LGTIGS.mjs";
@@ -24,4 +24,4 @@ export {
24
24
  JsonSchema,
25
25
  JsonSchema_exports
26
26
  };
27
- //# sourceMappingURL=chunk-QGMIH2SN.mjs.map
27
+ //# sourceMappingURL=chunk-QRZ2I3ZM.mjs.map
@@ -10,7 +10,7 @@ import {
10
10
  objectToJSON,
11
11
  removeTag,
12
12
  subscribe
13
- } from "./chunk-SJKBWMJY.mjs";
13
+ } from "./chunk-G54OX4IX.mjs";
14
14
  import {
15
15
  getDescription,
16
16
  getEntityKind,
@@ -122,4 +122,4 @@ export {
122
122
  removeTag2 as removeTag,
123
123
  Entity_exports
124
124
  };
125
- //# sourceMappingURL=chunk-LVGOVFDV.mjs.map
125
+ //# sourceMappingURL=chunk-SCPFDS2E.mjs.map
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  object
3
- } from "./chunk-FZHVQEHN.mjs";
3
+ } from "./chunk-PSZBLH53.mjs";
4
4
  import {
5
5
  getDXN,
6
6
  make
7
- } from "./chunk-SW5CUSBY.mjs";
7
+ } from "./chunk-J54QMAKF.mjs";
8
8
  import {
9
9
  FormInputAnnotation,
10
10
  IconAnnotation,
@@ -17,6 +17,7 @@ import {
17
17
  // src/Feed.ts
18
18
  var Feed_exports = {};
19
19
  __export(Feed_exports, {
20
+ ContextFeedService: () => ContextFeedService,
20
21
  Feed: () => Feed,
21
22
  FeedService: () => FeedService,
22
23
  Service: () => Service,
@@ -31,7 +32,7 @@ __export(Feed_exports, {
31
32
  remove: () => remove,
32
33
  runQuery: () => runQuery,
33
34
  setRetention: () => setRetention,
34
- unsafeFromQueueDXN: () => unsafeFromQueueDXN
35
+ sync: () => sync
35
36
  });
36
37
  import * as Context from "effect/Context";
37
38
  import * as Effect from "effect/Effect";
@@ -69,16 +70,6 @@ var getQueueDxn = (feed) => {
69
70
  self.echoId
70
71
  ]);
71
72
  };
72
- var unsafeFromQueueDXN = (queueDxn) => {
73
- const parts = queueDxn.asQueueDXN();
74
- if (!parts) {
75
- throw new Error(`Expected a queue DXN, got: ${queueDxn.toString()}`);
76
- }
77
- return make(Feed, {
78
- id: parts.queueId,
79
- namespace: parts.subspaceTag === "trace" ? "trace" : void 0
80
- });
81
- };
82
73
  var FeedService = class extends Context.Tag("@dxos/echo/Feed/FeedService")() {
83
74
  };
84
75
  var Service = FeedService;
@@ -91,8 +82,16 @@ var notAvailable = Layer.succeed(FeedService, {
91
82
  },
92
83
  query: () => {
93
84
  throw new Error("Feed.FeedService not available");
85
+ },
86
+ sync: () => {
87
+ throw new Error("Feed.FeedService not available");
94
88
  }
95
89
  });
90
+ var ContextFeedService = class _ContextFeedService extends Context.Tag("@dxos/echo/Feed/ContextFeedService")() {
91
+ static layer = (feed) => Layer.succeed(_ContextFeedService, {
92
+ feed
93
+ });
94
+ };
96
95
  var append = (feed, items) => Effect.gen(function* () {
97
96
  const service = yield* FeedService;
98
97
  yield* Effect.promise(() => service.append(feed, items));
@@ -104,6 +103,10 @@ var remove = (feed, items) => Effect.gen(function* () {
104
103
  });
105
104
  var query = (feed, queryOrFilter) => FeedService.pipe(Effect.map((service) => service.query(feed, queryOrFilter)));
106
105
  var runQuery = (feed, queryOrFilter) => query(feed, queryOrFilter).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));
106
+ var sync = (feed, options) => Effect.gen(function* () {
107
+ const service = yield* FeedService;
108
+ yield* Effect.promise(() => service.sync(feed, options));
109
+ });
107
110
  var cursor = (_feed) => Effect.succeed({
108
111
  _tag: "Cursor"
109
112
  });
@@ -115,18 +118,19 @@ export {
115
118
  Feed,
116
119
  make2 as make,
117
120
  getQueueDxn,
118
- unsafeFromQueueDXN,
119
121
  FeedService,
120
122
  Service,
121
123
  notAvailable,
124
+ ContextFeedService,
122
125
  append,
123
126
  remove,
124
127
  query,
125
128
  runQuery,
129
+ sync,
126
130
  cursor,
127
131
  next,
128
132
  nextOption,
129
133
  setRetention,
130
134
  Feed_exports
131
135
  };
132
- //# sourceMappingURL=chunk-S7IMFVTB.mjs.map
136
+ //# sourceMappingURL=chunk-ZFACXBY6.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/Feed.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Context from 'effect/Context';\nimport * as Effect from 'effect/Effect';\nimport * as Layer from 'effect/Layer';\nimport type * as Option from 'effect/Option';\nimport * as Schema from 'effect/Schema';\n\nimport { DXN } from '@dxos/keys';\n\nimport * as Annotation from './Annotation';\nimport type * as Entity from './Entity';\nimport type * as Filter from './Filter';\nimport * as internal from './internal';\nimport * as Obj from './Obj';\nimport type * as Query from './Query';\nimport type * as QueryResult from './QueryResult';\nimport * as Type from './Type';\n\n/**\n * Runtime schema for a Feed object.\n *\n * @example\n * ```ts\n * const feed = Obj.make(Feed.Feed, { name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });\n * ```\n */\nexport const Feed = Schema.Struct({\n /** User-facing display name. */\n name: Schema.String.pipe(Schema.optional),\n /** Identifier for the feed's kind (e.g., plugin id). */\n kind: Schema.String.pipe(internal.FormInputAnnotation.set(false), Schema.optional),\n\n /**\n * Feed namespace.\n * Controls how feed data is stored and replicated.\n * - `data`: Data feed (default).\n * - `trace`: Trace feed.\n */\n namespace: Schema.optional(Schema.Literal('data', 'trace')),\n}).pipe(\n Type.object({\n typename: 'org.dxos.type.feed',\n version: '0.1.0',\n }),\n internal.SystemTypeAnnotation.set(true),\n Annotation.IconAnnotation.set({\n icon: 'ph--rows--regular',\n hue: 'yellow',\n }),\n);\n\n/**\n * TypeScript instance type for a Feed object.\n */\nexport interface Feed extends Schema.Schema.Type<typeof Feed> {}\n\n//\n// Types\n//\n\n/**\n * Opaque cursor for iterating over feed items.\n */\n// TODO(dmaretskyi): T needs to be referenced in the type structure for typescript to respect it during inference and type-checking.\nexport interface Cursor<T = Obj.Snapshot> {\n readonly _tag: 'Cursor';\n}\n\n/**\n * Retention options for a feed.\n */\nexport interface RetentionOptions {\n /** Retain items after this cursor position. */\n // TODO(wittjosiah): Use FeedCursor from @dxos/feed?\n cursor?: string;\n}\n\n/**\n * Sync options for a feed.\n */\nexport interface SyncOptions {\n /** Push local changes to the server. Defaults to true. */\n shouldPush?: boolean;\n /** Pull remote changes from the server. Defaults to true. */\n shouldPull?: boolean;\n}\n\n//\n// Factory\n//\n\n/**\n * Creates a new feed object.\n *\n * @example\n * ```ts\n * const feed = Feed.make({ name: 'notifications', kind: 'org.dxos.plugin.notifications.v1' });\n * ```\n */\n// TODO(wittjosiah): How to control the feed namespace (data/trace)? Why do feeds have namespaces?\nexport const make = (props: Obj.MakeProps<typeof Feed> = {}): Feed => Obj.make(Feed, props);\n\n/**\n * Derives the queue DXN from the feed object's DXN.\n * Returns `undefined` when the feed is not stored in a space yet.\n *\n * Used internally by the feed service layer.\n */\nexport const getQueueDxn = (feed: Feed): DXN | undefined => {\n const self = Obj.getDXN(feed).asEchoDXN();\n if (!self || !self.spaceId) {\n return undefined;\n }\n return new DXN(DXN.kind.QUEUE, [feed.namespace ?? 'data', self.spaceId, self.echoId]);\n};\n\n//\n// Service\n//\n\n/**\n * Effect service for feed operations.\n * Provides the bridge to the underlying storage implementation.\n * Must be provided by the application layer (e.g., echo-db).\n */\nexport class FeedService extends Context.Tag('@dxos/echo/Feed/FeedService')<\n FeedService,\n {\n /**\n * Appends items to a feed.\n */\n append(feed: Feed, items: Entity.Unknown[]): Promise<void>;\n\n /**\n * Removes items from a feed by ID.\n */\n // TODO(dmaretskyi): Change type to ObjectId.\n remove(feed: Feed, ids: string[]): Promise<void>;\n\n /**\n * Queries items in a feed.\n */\n query: {\n <Q extends Query.Any>(feed: Feed, query: Q): QueryResult.QueryResult<Query.Type<Q>>;\n <F extends Filter.Any>(feed: Feed, filter: F): QueryResult.QueryResult<Filter.Type<F>>;\n };\n\n /**\n * Syncs the feed with the server.\n */\n sync(feed: Feed, options?: SyncOptions): Promise<void>;\n }\n>() {}\n\n/**\n * @deprecated Use `FeedService` instead.\n */\nexport type Service = FeedService;\n\n/**\n * @deprecated Use `FeedService` instead.\n */\nexport const Service = FeedService;\n\n/**\n * Layer that provides a Feed service that throws when accessed.\n * Useful as a default layer when no feed service is available.\n */\nexport const notAvailable: Layer.Layer<FeedService> = Layer.succeed(FeedService, {\n append: () => {\n throw new Error('Feed.FeedService not available');\n },\n remove: () => {\n throw new Error('Feed.FeedService not available');\n },\n query: () => {\n throw new Error('Feed.FeedService not available');\n },\n sync: () => {\n throw new Error('Feed.FeedService not available');\n },\n} as Context.Tag.Service<FeedService>);\n\n//\n// Context (per-call) service\n//\n\n/**\n * Effect service exposing a single `Feed.Feed` as the \"current\" feed for a call site.\n *\n * @deprecated Prefer threading a `Feed.Feed` explicitly through function signatures\n * over hiding it behind a context service.\n */\nexport class ContextFeedService extends Context.Tag('@dxos/echo/Feed/ContextFeedService')<\n ContextFeedService,\n {\n readonly feed: Feed;\n }\n>() {\n static layer = (feed: Feed): Layer.Layer<ContextFeedService> => Layer.succeed(ContextFeedService, { feed });\n}\n\n//\n// Operations\n//\n\n/**\n * Appends items to a feed.\n *\n * @example\n * ```ts\n * yield* Feed.append(feed, [Obj.make(Notification, { title: 'Hello' })]);\n * ```\n */\nexport const append = (feed: Feed, items: Entity.Unknown[]): Effect.Effect<void, never, FeedService> =>\n Effect.gen(function* () {\n const service = yield* FeedService;\n yield* Effect.promise(() => service.append(feed, items));\n });\n\n/**\n * Removes items from a feed.\n *\n * @example\n * ```ts\n * yield* Feed.remove(feed, [item]);\n * ```\n */\n// TODO(dmaretskyi): Should we allow snapshots here? - what does it mean to remove a snapshot?\nexport const remove = (feed: Feed, items: (Entity.Unknown | Obj.Snapshot)[]): Effect.Effect<void, never, FeedService> =>\n Effect.gen(function* () {\n const service = yield* FeedService;\n const ids = items.map((item) => item.id);\n yield* Effect.promise(() => service.remove(feed, ids));\n });\n\n/**\n * Creates a reactive query over items in a feed.\n *\n * @example\n * ```ts\n * const result = yield* Feed.query(feed, Filter.type(Person));\n * ```\n */\n// TODO(dmaretskyi): Suport chained queries:\n// const result = yield* feed.pipe(Feed.query(Filter.type(Person))); result.subscribe(...)\n// const objects = yield* feed.pipe(Feed.query(Filter.type(Person))).run;\n// const object = yield* feed.pipe(Feed.query(Filter.type(Person))).first;\n// ... unify for Database and schema queries.\nexport const query: {\n <Q extends Query.Any>(\n feed: Feed,\n query: Q,\n ): Effect.Effect<QueryResult.QueryResult<Query.Type<Q>>, never, FeedService>;\n <F extends Filter.Any>(\n feed: Feed,\n filter: F,\n ): Effect.Effect<QueryResult.QueryResult<Filter.Type<F>>, never, FeedService>;\n} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>\n FeedService.pipe(Effect.map((service) => service.query(feed, queryOrFilter as any) as QueryResult.QueryResult<any>));\n\n/**\n * Executes a feed query once and returns the results.\n *\n * @example\n * ```ts\n * const items = yield* Feed.runQuery(feed, Filter.type(Person));\n * ```\n */\nexport const runQuery: {\n <Q extends Query.Any>(feed: Feed, query: Q): Effect.Effect<Query.Type<Q>[], never, FeedService>;\n <F extends Filter.Any>(feed: Feed, filter: F): Effect.Effect<Filter.Type<F>[], never, FeedService>;\n} = (feed: Feed, queryOrFilter: Query.Any | Filter.Any) =>\n query(feed, queryOrFilter as any).pipe(Effect.flatMap((queryResult) => Effect.promise(() => queryResult.run())));\n\n/**\n * Syncs the feed with the server.\n *\n * @example\n * ```ts\n * yield* Feed.sync(feed);\n * yield* Feed.sync(feed, { shouldPush: false });\n * ```\n */\nexport const sync = (feed: Feed, options?: SyncOptions): Effect.Effect<void, never, FeedService> =>\n Effect.gen(function* () {\n const service = yield* FeedService;\n yield* Effect.promise(() => service.sync(feed, options));\n });\n\n/**\n * Creates a cursor for iterating over feed items.\n * Currently stubbed — cursor operations are not yet implemented.\n *\n * @example\n * ```ts\n * const cursor = yield* Feed.cursor<Person>(feed);\n * const item = yield* Feed.next(cursor);\n * ```\n */\n// TODO(wittjosiah): Implement cursor operations. Use Effect streams?\nexport const cursor = <T = Obj.Snapshot>(_feed: Feed): Effect.Effect<Cursor<T>, never, FeedService> =>\n Effect.succeed({ _tag: 'Cursor' } as Cursor<T>);\n\n/**\n * Returns the next item from a feed cursor.\n * Currently stubbed — cursor operations are not yet implemented.\n */\nexport const next = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<T, never, FeedService> =>\n Effect.die('Feed.next is not yet implemented');\n\n/**\n * Returns the next item from a feed cursor as an Option.\n * Currently stubbed — cursor operations are not yet implemented.\n */\nexport const nextOption = <T = Obj.Snapshot>(_cursor: Cursor<T>): Effect.Effect<Option.Option<T>, never, FeedService> =>\n Effect.die('Feed.nextOption is not yet implemented');\n\n/**\n * Sets the local retention policy for a feed.\n * Currently stubbed — feeds do not yet support retention.\n *\n * @example\n * ```ts\n * yield* Feed.setRetention(feed, { count: 1000 });\n * ```\n */\n// TODO(dmaretskyi): Implement when feed retention is supported.\nexport const setRetention = (_feed: Feed, _options: RetentionOptions): Effect.Effect<void, never, FeedService> =>\n Effect.void;\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;AAAA;;;;;;;;;cAAAA;EAAA;;;;;;;;;AAMA,YAAYC,aAAa;AACzB,YAAYC,YAAY;AACxB,YAAYC,WAAW;AAEvB,YAAYC,YAAY;AAExB,SAASC,WAAW;AAmBb,IAAMC,OAAcC,cAAO;;EAEhCC,MAAaC,cAAOC,KAAYC,eAAQ;;EAExCC,MAAaH,cAAOC,KAAcG,oBAAoBC,IAAI,KAAA,GAAeH,eAAQ;;;;;;;EAQjFI,WAAkBJ,gBAAgBK,eAAQ,QAAQ,OAAA,CAAA;AACpD,CAAA,EAAGN,KACIO,OAAO;EACVC,UAAU;EACVC,SAAS;AACX,CAAA,GACSC,qBAAqBN,IAAI,IAAA,GACvBO,eAAeP,IAAI;EAC5BQ,MAAM;EACNC,KAAK;AACP,CAAA,CAAA;AAoDK,IAAMC,QAAO,CAACC,QAAoC,CAAC,MAAgBD,KAAKlB,MAAMmB,KAAAA;AAQ9E,IAAMC,cAAc,CAACC,SAAAA;AAC1B,QAAMC,OAAWC,OAAOF,IAAAA,EAAMG,UAAS;AACvC,MAAI,CAACF,QAAQ,CAACA,KAAKG,SAAS;AAC1B,WAAOC;EACT;AACA,SAAO,IAAIC,IAAIA,IAAIrB,KAAKsB,OAAO;IAACP,KAAKZ,aAAa;IAAQa,KAAKG;IAASH,KAAKO;GAAO;AACtF;AAWO,IAAMC,cAAN,cAAkCC,YAAI,6BAAA,EAAA,EAAA;AA2BxC;AAUE,IAAMC,UAAUF;AAMhB,IAAMG,eAA+CC,cAAQJ,aAAa;EAC/EK,QAAQ,MAAA;AACN,UAAM,IAAIC,MAAM,gCAAA;EAClB;EACAC,QAAQ,MAAA;AACN,UAAM,IAAID,MAAM,gCAAA;EAClB;EACAE,OAAO,MAAA;AACL,UAAM,IAAIF,MAAM,gCAAA;EAClB;EACAG,MAAM,MAAA;AACJ,UAAM,IAAIH,MAAM,gCAAA;EAClB;AACF,CAAA;AAYO,IAAMI,qBAAN,MAAMA,4BAAmCT,YAAI,oCAAA,EAAA,EAAA;EAMlD,OAAOU,QAAQ,CAACpB,SAAsDa,cAAQM,qBAAoB;IAAEnB;EAAK,CAAA;AAC3G;AAcO,IAAMc,SAAS,CAACd,MAAYqB,UAC1BC,WAAI,aAAA;AACT,QAAMC,UAAU,OAAOd;AACvB,SAAce,eAAQ,MAAMD,QAAQT,OAAOd,MAAMqB,KAAAA,CAAAA;AACnD,CAAA;AAWK,IAAML,SAAS,CAAChB,MAAYqB,UAC1BC,WAAI,aAAA;AACT,QAAMC,UAAU,OAAOd;AACvB,QAAMgB,MAAMJ,MAAMK,IAAI,CAACC,SAASA,KAAKC,EAAE;AACvC,SAAcJ,eAAQ,MAAMD,QAAQP,OAAOhB,MAAMyB,GAAAA,CAAAA;AACnD,CAAA;AAeK,IAAMR,QAST,CAACjB,MAAY6B,kBACfpB,YAAY1B,KAAY2C,WAAI,CAACH,YAAYA,QAAQN,MAAMjB,MAAM6B,aAAAA,CAAAA,CAAAA;AAUxD,IAAMC,WAGT,CAAC9B,MAAY6B,kBACfZ,MAAMjB,MAAM6B,aAAAA,EAAsB9C,KAAYgD,eAAQ,CAACC,gBAAuBR,eAAQ,MAAMQ,YAAYC,IAAG,CAAA,CAAA,CAAA;AAWtG,IAAMf,OAAO,CAAClB,MAAYkC,YACxBZ,WAAI,aAAA;AACT,QAAMC,UAAU,OAAOd;AACvB,SAAce,eAAQ,MAAMD,QAAQL,KAAKlB,MAAMkC,OAAAA,CAAAA;AACjD,CAAA;AAaK,IAAMC,SAAS,CAAmBC,UAChCvB,eAAQ;EAAEwB,MAAM;AAAS,CAAA;AAM3B,IAAMC,OAAO,CAAmBC,YAC9BC,WAAI,kCAAA;AAMN,IAAMC,aAAa,CAAmBF,YACpCC,WAAI,wCAAA;AAYN,IAAME,eAAe,CAACN,OAAaO,aACjCC;",
6
+ "names": ["make", "Context", "Effect", "Layer", "Schema", "DXN", "Feed", "Struct", "name", "String", "pipe", "optional", "kind", "FormInputAnnotation", "set", "namespace", "Literal", "object", "typename", "version", "SystemTypeAnnotation", "IconAnnotation", "icon", "hue", "make", "props", "getQueueDxn", "feed", "self", "getDXN", "asEchoDXN", "spaceId", "undefined", "DXN", "QUEUE", "echoId", "FeedService", "Tag", "Service", "notAvailable", "succeed", "append", "Error", "remove", "query", "sync", "ContextFeedService", "layer", "items", "gen", "service", "promise", "ids", "map", "item", "id", "queryOrFilter", "runQuery", "flatMap", "queryResult", "run", "options", "cursor", "_feed", "_tag", "next", "_cursor", "die", "nextOption", "setRetention", "_options", "void"]
7
+ }
@@ -6,13 +6,13 @@ import {
6
6
  Json_exports,
7
7
  QueryAST,
8
8
  View_exports
9
- } from "./chunk-QXIANHKU.mjs";
9
+ } from "./chunk-MGSQGHOD.mjs";
10
10
  import {
11
11
  SchemaRegistry_exports
12
12
  } from "./chunk-BICZKPQG.mjs";
13
13
  import {
14
14
  Tag_exports
15
- } from "./chunk-HPNQTEEQ.mjs";
15
+ } from "./chunk-Q2KKKJSV.mjs";
16
16
  import {
17
17
  Order_exports
18
18
  } from "./chunk-TTCSATUD.mjs";
@@ -21,7 +21,7 @@ import {
21
21
  } from "./chunk-7RVZT53K.mjs";
22
22
  import {
23
23
  Migration_exports
24
- } from "./chunk-SUZMWP3Y.mjs";
24
+ } from "./chunk-FIWO2FZK.mjs";
25
25
  import {
26
26
  Extension_exports
27
27
  } from "./chunk-GWFFC34K.mjs";
@@ -30,45 +30,45 @@ import {
30
30
  } from "./chunk-44HT3MEC.mjs";
31
31
  import {
32
32
  Relation_exports
33
- } from "./chunk-WRVRDZDA.mjs";
33
+ } from "./chunk-PT37DG2F.mjs";
34
34
  import {
35
35
  JsonSchema_exports
36
- } from "./chunk-QGMIH2SN.mjs";
36
+ } from "./chunk-QRZ2I3ZM.mjs";
37
37
  import {
38
38
  QueryResult_exports
39
39
  } from "./chunk-V72DY6LU.mjs";
40
40
  import {
41
41
  Query_exports
42
- } from "./chunk-VGKLHHRT.mjs";
42
+ } from "./chunk-Q7ZL2P5H.mjs";
43
43
  import {
44
44
  Feed_exports
45
- } from "./chunk-S7IMFVTB.mjs";
45
+ } from "./chunk-ZFACXBY6.mjs";
46
46
  import {
47
47
  Type_exports
48
- } from "./chunk-FZHVQEHN.mjs";
48
+ } from "./chunk-PSZBLH53.mjs";
49
49
  import {
50
50
  Filter_exports
51
- } from "./chunk-RF7ZBZ4A.mjs";
51
+ } from "./chunk-APJKDGFL.mjs";
52
52
  import {
53
53
  Obj_exports
54
- } from "./chunk-SW5CUSBY.mjs";
54
+ } from "./chunk-J54QMAKF.mjs";
55
55
  import {
56
56
  Ref_exports
57
- } from "./chunk-VYAGNFSJ.mjs";
57
+ } from "./chunk-N7VOEPSV.mjs";
58
58
  import {
59
59
  Entity_exports
60
- } from "./chunk-LVGOVFDV.mjs";
61
- import "./chunk-SJKBWMJY.mjs";
62
- import "./chunk-6VIJV543.mjs";
63
- import "./chunk-O5LRY6CO.mjs";
60
+ } from "./chunk-SCPFDS2E.mjs";
61
+ import "./chunk-G54OX4IX.mjs";
62
+ import "./chunk-APHSOTIX.mjs";
63
+ import "./chunk-MLS7U7AT.mjs";
64
64
  import "./chunk-TRPZU2HV.mjs";
65
- import "./chunk-MPAI2MHO.mjs";
65
+ import "./chunk-BMB7IHGB.mjs";
66
66
  import {
67
67
  Annotation_exports
68
68
  } from "./chunk-5SL5LDLD.mjs";
69
69
  import {
70
70
  Database_exports
71
- } from "./chunk-FHYIM4RD.mjs";
71
+ } from "./chunk-I2DARWPX.mjs";
72
72
  import "./chunk-TNBK56IN.mjs";
73
73
  import "./chunk-N4B7FHQT.mjs";
74
74
  import {
@@ -106,10 +106,10 @@ import {
106
106
  updateFieldsInSchema,
107
107
  version,
108
108
  versionValid
109
- } from "../chunk-SJKBWMJY.mjs";
109
+ } from "../chunk-G54OX4IX.mjs";
110
110
  import {
111
111
  RefArray
112
- } from "../chunk-6VIJV543.mjs";
112
+ } from "../chunk-APHSOTIX.mjs";
113
113
  import {
114
114
  CustomAnnotations,
115
115
  DecodedAnnotations,
@@ -126,7 +126,7 @@ import {
126
126
  toEffectSchema,
127
127
  toJsonSchema,
128
128
  toPropType
129
- } from "../chunk-O5LRY6CO.mjs";
129
+ } from "../chunk-MLS7U7AT.mjs";
130
130
  import {
131
131
  Currency,
132
132
  CurrencyAnnotationId,
@@ -171,8 +171,8 @@ import {
171
171
  getSchemaReference,
172
172
  refFromEncodedReference,
173
173
  setRefResolver
174
- } from "../chunk-MPAI2MHO.mjs";
175
- import "../chunk-FHYIM4RD.mjs";
174
+ } from "../chunk-BMB7IHGB.mjs";
175
+ import "../chunk-I2DARWPX.mjs";
176
176
  import {
177
177
  ATTR_PARENT,
178
178
  ATTR_TYPE,