Compare commits

...

38 Commits

Author SHA1 Message Date
54fa433d1a v7.1.3
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-03-26 07:50:29 +00:00
de23b44a23 fix(deps): bump development dependencies for tooling and Node types 2026-03-26 07:50:29 +00:00
1c4f50fbd6 v7.1.2
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-03-24 19:51:53 +00:00
3270aa2042 fix(docs): refresh project guidance for TC39 decorators, build configuration, and dependency compatibility 2026-03-24 19:51:52 +00:00
b0dc5f8a60 v7.1.1
Some checks failed
Default (tags) / security (push) Failing after 0s
Default (tags) / test (push) Failing after 0s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-03-24 19:44:49 +00:00
03431535d7 fix(build): update build and test tooling configuration, migrate project config to .smartconfig.json, and align TypeScript typings 2026-03-24 19:44:49 +00:00
27c1500db5 v7.1.0
Some checks failed
Default (tags) / security (push) Successful in 30s
Default (tags) / test (push) Failing after 52s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-02-26 17:01:37 +00:00
3bbb78add8 feat(config): normalize npmextra.json to namespaced keys and add CI/release configuration 2026-02-26 17:01:37 +00:00
9d779329e1 v7.0.16
Some checks failed
Default (tags) / security (push) Successful in 48s
Default (tags) / test (push) Failing after 55s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-02-26 16:58:04 +00:00
cdc6b029af fix(mongodb): set default socketTimeoutMS to 30000ms in MongoClient options to prevent hung operations from holding connections 2026-02-26 16:58:04 +00:00
39c0ba7bea v7.0.15
Some checks failed
Default (tags) / security (push) Successful in 51s
Default (tags) / test (push) Failing after 51s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-12-01 11:48:28 +00:00
e4faca88ba fix(classes.doc): Avoid emitting instance fields for collection and manager to preserve decorator-defined prototype getters 2025-12-01 11:48:28 +00:00
40bc408d8f v7.0.14
Some checks failed
Default (tags) / security (push) Successful in 52s
Default (tags) / test (push) Failing after 50s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 15:45:15 +00:00
3c8308561e fix(classes.collection): Centralize TC39 decorator metadata initialization and use context.metadata in class decorators 2025-11-28 15:45:15 +00:00
49b121aa5b v7.0.13
Some checks failed
Default (tags) / security (push) Successful in 41s
Default (tags) / test (push) Failing after 49s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 11:40:52 +00:00
514d3dbd29 fix(classes.doc): Remove noisy debug logging from decorators and serialization logic 2025-11-28 11:40:52 +00:00
2b7316dc46 v7.0.12
Some checks failed
Default (tags) / security (push) Successful in 54s
Default (tags) / test (push) Failing after 1m16s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 11:27:36 +00:00
11a1345891 fix(collection): Ensure TC39 decorator metadata is initialized on both original and decorated constructors/prototypes and add debug logging 2025-11-28 11:27:36 +00:00
2fe3a72eaf 7.0.11
Some checks failed
Default (tags) / security (push) Successful in 56s
Default (tags) / test (push) Failing after 1m18s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 11:19:45 +00:00
fb7e82557b chore: Remove debug logging from Collection decorator 2025-11-28 11:19:44 +00:00
8a3425e554 7.0.10
Some checks failed
Default (tags) / security (push) Successful in 58s
Default (tags) / test (push) Failing after 1m20s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 11:17:25 +00:00
d2092cc5f3 chore(debug): Add metadata debug logging to Collection decorator 2025-11-28 11:17:25 +00:00
1a621ca64e v7.0.9
Some checks failed
Default (tags) / security (push) Successful in 38s
Default (tags) / test (push) Failing after 50s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 11:02:39 +00:00
f6cc07880a fix(classes.collection): Fix closure bug in Collection decorator by defining collection getter on original constructor and prototype 2025-11-28 11:02:39 +00:00
bf4b11f1f5 v7.0.8
Some checks failed
Default (tags) / security (push) Successful in 46s
Default (tags) / test (push) Failing after 51s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 10:55:29 +00:00
181e9da151 fix(classes.collection): Fix closure issue in managed decorator so Class.collection/instance.collection resolve correctly 2025-11-28 10:55:29 +00:00
3013edb2eb v7.0.7
Some checks failed
Default (tags) / security (push) Successful in 38s
Default (tags) / test (push) Failing after 49s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 10:17:07 +00:00
604e4ba265 fix(decorators): Fix decorator metadata initialization and Lucene query transformation 2025-11-28 10:17:07 +00:00
477f446c34 v7.0.6
Some checks failed
Default (tags) / security (push) Successful in 49s
Default (tags) / test (push) Failing after 50s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 10:03:23 +00:00
fbb8bb685c fix(classes.collection): Guard against missing collection before attaching document constructor in Collection decorator 2025-11-28 10:03:23 +00:00
4cf62fd91c v7.0.5
Some checks failed
Default (tags) / security (push) Successful in 50s
Default (tags) / test (push) Failing after 50s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 09:37:32 +00:00
8ee45c5646 fix(package): Add package exports entry and remove legacy main/typings fields 2025-11-28 09:37:32 +00:00
12f1630adf v7.0.4
Some checks failed
Default (tags) / security (push) Successful in 48s
Default (tags) / test (push) Failing after 50s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 09:16:52 +00:00
0a349180b2 fix(decorators): Add Symbol.metadata polyfill and import it at entry to ensure decorator metadata is available 2025-11-28 09:16:52 +00:00
23aa29a5b8 v7.0.3
Some checks failed
Default (tags) / security (push) Successful in 49s
Default (tags) / test (push) Failing after 50s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 08:54:48 +00:00
5bf2aae2b9 fix(build): Bump devDependency @git.zone/tsbuild to ^3.1.2 2025-11-28 08:54:48 +00:00
5cf9155205 v7.0.2
Some checks failed
Default (tags) / security (push) Successful in 51s
Default (tags) / test (push) Failing after 51s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-11-28 07:53:15 +00:00
ef5491075f fix(collectionfactory): Simplify CollectionFactory.getCollection: remove unnecessary IIFE and instantiate collection only when dbArg is SmartdataDb 2025-11-28 07:53:15 +00:00
34 changed files with 4544 additions and 9398 deletions

View File

@@ -7,7 +7,7 @@ on:
env:
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@code.foss.global/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}

View File

@@ -7,7 +7,7 @@ on:
env:
IMAGE: code.foss.global/host.today/ht-docker-node:npmci
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@/${{gitea.repository}}.git
NPMCI_COMPUTED_REPOURL: https://${{gitea.repository_owner}}:${{secrets.GITEA_TOKEN}}@code.foss.global/${{gitea.repository}}.git
NPMCI_TOKEN_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}

10
.gitignore vendored
View File

@@ -16,4 +16,12 @@ node_modules/
dist/
dist_*/
#------# custom
# rust
rust/target/
dist_rust/
# AI
.claude/
.serena/
#------# custom

View File

@@ -1,15 +1,5 @@
{
"npmdocker": {
"baseImage": "hosttoday/ht-docker-node:mongo",
"command": "npmci test stable",
"dockerSock": false
},
"npmci": {
"npmGlobalTools": [],
"npmAccessLevel": "public",
"npmRegistryUrl": "registry.npmjs.org"
},
"gitzone": {
"@git.zone/cli": {
"projectType": "npm",
"module": {
"githost": "code.foss.global",
@@ -28,9 +18,25 @@
"custom data types",
"ODM"
]
},
"release": {
"registries": [
"https://verdaccio.lossless.digital",
"https://registry.npmjs.org"
],
"accessLevel": "public"
}
},
"tsdoc": {
"@git.zone/tsdoc": {
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
},
"@git.zone/tsdocker": {
"baseImage": "hosttoday/ht-docker-node:mongo",
"command": "npmci test stable",
"dockerSock": false
},
"@ship.zone/szci": {
"npmGlobalTools": [],
"npmRegistryUrl": "registry.npmjs.org"
}
}
}

View File

@@ -1,7 +1,7 @@
{
"json.schemas": [
{
"fileMatch": ["/npmextra.json"],
"fileMatch": ["/.smartconfig.json"],
"schema": {
"type": "object",
"properties": {
@@ -22,6 +22,5 @@
}
}
}
],
"deno.enable": false
]
}

View File

@@ -1,18 +1,157 @@
# Changelog
## 2026-03-26 - 7.1.3 - fix(deps)
bump development dependencies for tooling and Node types
- update @git.zone/tsrun from ^2.0.1 to ^2.0.2
- update @git.zone/tstest from ^3.5.1 to ^3.6.0
- update @types/node from ^22.15.2 to ^25.5.0
## 2026-03-24 - 7.1.2 - fix(docs)
refresh project guidance for TC39 decorators, build configuration, and dependency compatibility
- streamlines readme hints to focus on current decorator patterns and runtime support
- adds compatibility notes for the updated build toolchain and dependency APIs
- includes the project license file in the repository
## 2026-03-24 - 7.1.1 - fix(build)
update build and test tooling configuration, migrate project config to .smartconfig.json, and align TypeScript typings
- Switch the build script to tsbuild tsfolders and upgrade core build/test dependencies including @git.zone/tsbuild, @git.zone/tstest, and @git.zone/tsrun.
- Replace npmextra.json with .smartconfig.json and update package packaging to include the new config file.
- Update test files to import tapbundle from @git.zone/tstest/tapbundle and remove the standalone @push.rocks/tapbundle dependency.
- Adjust TypeScript configuration and source typings for stricter compatibility, including node types and definite assignment/nullability fixes.
- Fix Gitea workflow repository URLs for code.foss.global and expand .gitignore for generated Rust and local tooling directories.
## 2026-02-26 - 7.1.0 - feat(config)
normalize npmextra.json to namespaced keys and add CI/release configuration
- Replaced legacy keys (npmdocker, npmci, gitzone, tsdoc) with namespaced package keys (@git.zone/cli, @git.zone/tsdoc, @git.zone/tsdocker, @ship.zone/szci).
- Moved tsdoc legal text under @git.zone/tsdoc.
- Added release configuration with registries (https://verdaccio.lossless.digital and https://registry.npmjs.org) and accessLevel public under @git.zone/cli.
- Added @git.zone/tsdocker CI/docker settings and @ship.zone/szci npm registry/tooling settings.
- Removed old top-level entries to consolidate tooling configuration under scoped keys.
## 2026-02-26 - 7.0.16 - fix(mongodb)
set default socketTimeoutMS to 30000ms in MongoClient options to prevent hung operations from holding connections
- Adds socketTimeoutMS: 30000 to MongoClient clientOptions in ts/classes.db.ts
- Helps prevent hung operations from indefinitely holding connections by enforcing a 30s socket timeout
- Non-breaking change (defaults only)
## 2025-12-01 - 7.0.15 - fix(classes.doc)
Avoid emitting instance fields for collection and manager to preserve decorator-defined prototype getters
- ts/classes.doc.ts: changed instance properties `collection` and `manager` to `declare` so TypeScript does not emit them as own properties — prevents ES2022 class fields from shadowing prototype getters created by @Collection and @managed decorators.
- readme.hints.md: added documentation explaining the ES2022 class fields issue and recommending use of `declare` for type-only instance properties; marks the fix as v7.0.15.
## 2025-11-28 - 7.0.14 - fix(classes.collection)
Centralize TC39 decorator metadata initialization and use context.metadata in class decorators
- Add initializeDecoratorMetadata helper to initialize prototype and constructor properties from TC39 decorator metadata
- Refactor Collection and managed decorators to call initializeDecoratorMetadata with context.metadata
- Remove direct reliance on constructor[Symbol.metadata] in class decorators to avoid read-only assignment issues
- Ensure consistent initialization of saveableProperties, globalSaveableProperties, uniqueIndexes, regularIndexes, searchableFields and \_svDbOptions
## 2025-11-28 - 7.0.13 - fix(classes.doc)
Remove noisy debug logging from decorators and serialization logic
- Removed debug logger calls from globalSvDb decorator initialization
- Removed debug logger calls from svDb decorator initialization and svDb options handling
- Removed debug logger calls from unI and index decorator initializers
- Removed debug logging in createSavableObject to reduce console noise; no functional changes
## 2025-11-28 - 7.0.12 - fix(collection)
Ensure TC39 decorator metadata is initialized on both original and decorated constructors/prototypes and add debug logging
- Initialize metadata-driven prototype properties (globalSaveableProperties, saveableProperties, uniqueIndexes, regularIndexes) on both the decorated class prototype and the original constructor prototype to avoid closure/compatibility issues
- Initialize searchableFields on both the decorated constructor and the original constructor so text-index creation and searches see the fields correctly
- Forward and initialize \_svDbOptions from decorator metadata onto the original constructor to preserve custom serialization options
- Add debug logging in the Collection decorator and in createSavableObject to surface metadata and saveable-property counts for easier troubleshooting
## 2025-11-28 - 7.0.9 - fix(classes.collection)
Fix closure bug in Collection decorator by defining collection getter on original constructor and prototype
- Define the collection getter on the original constructor so class-level references (e.g. `User.collection`) resolve to the decorated collection instead of the original constructor's closure value.
- Also define the getter on the original constructor's prototype to ensure instance access works consistently across runtimes (Deno/Node).
## 2025-11-28 - 7.0.8 - fix(classes.collection)
Fix closure issue in managed decorator so Class.collection/instance.collection resolve correctly
- Resolve closure bug in the managed() decorator where class methods referencing Class.collection (or instance.collection) could receive the original constructor's captured value and thus the wrong collection/manager.
- Define dynamic getters on the original constructor and its prototype that compute the collection from the proper manager/db at access time (supports direct manager objects, delayed manager factory functions, and fallback to defaultManager).
- Getters are defined as non-enumerable and configurable to preserve compatibility with existing consumers.
## 2025-11-28 - 7.0.7 - fix(decorators)
Fix decorator metadata initialization and Lucene query transformation
- Ensure TC39 decorator metadata is used to initialize prototype properties so decorators work reliably across runtimes (context.metadata / Symbol.metadata shim imported early).
- Field and class decorators now populate and consume metadata for saveable properties, indexes and searchable fields so prototype initialization happens before instance creation.
- Fix Lucene -> MongoDB transformer to produce correct $or/$and/$not structures and improve wildcard/fuzzy/range handling for search queries.
- Improve collection initialization to auto-create compound text indexes from searchableFields and ensure index creation is idempotent.
## 2025-11-28 - 7.0.6 - fix(classes.collection)
Guard against missing collection before attaching document constructor in Collection decorator
- Added a truthy check for `coll` before setting `(coll as any).docCtor` in the Collection decorator (ts/classes.collection.ts).
- Prevents a potential TypeError when `collectionFactory.getCollection` returns null/undefined during decorator initialization.
## 2025-11-28 - 7.0.5 - fix(package)
Add package exports entry and remove legacy main/typings fields
- Added an "exports" entry in package.json mapping "." to ./dist_ts/index.js to declare the package's ESM entrypoint.
- Removed legacy "main" and "typings" fields from package.json.
- Improves Node/module resolution and modern bundler compatibility by using the package exports field.
## 2025-11-28 - 7.0.4 - fix(decorators)
Add Symbol.metadata polyfill and import it at entry to ensure decorator metadata is available
- Add ts/shim.ts: defines Symbol.metadata when missing (polyfill for TC39 Stage 3 decorator metadata).
- Import './shim.js' at the very top of ts/index.ts so the polyfill runs before any decorator code or exports are evaluated.
- Prevents runtime errors when decorators rely on Symbol.metadata and improves compatibility across runtimes/environments.
## 2025-11-28 - 7.0.3 - fix(build)
Bump devDependency @git.zone/tsbuild to ^3.1.2
- Updated @git.zone/tsbuild in devDependencies from ^3.1.1 to ^3.1.2
## 2025-11-28 - 7.0.2 - fix(collectionfactory)
Simplify CollectionFactory.getCollection: remove unnecessary IIFE and instantiate collection only when dbArg is SmartdataDb
- Remove redundant IIFE wrapper in getCollection for improved readability
- Only create and cache a SmartdataCollection when dbArg is an instance of SmartdataDb
- Avoid assigning undefined to the collections map by guarding instantiation and returning existing collection
## 2025-11-27 - 7.0.1 - fix(build)
Update build tooling and TypeScript compilation target
- Bump devDependency @git.zone/tsbuild from ^3.1.0 to ^3.1.1.
- Update tsconfig.json compiler target from ES2022 to ES2024 (affects emitted JS language level).
## 2025-11-27 - 7.0.0 - BREAKING CHANGE(mongodb)
Upgrade dependencies: bump mongodb to ^7.0.0 and @git.zone/tstest to ^3.1.3
- Bump 'mongodb' dependency from ^6.20.0 to ^7.0.0 — major version upgrade; may introduce breaking API changes and require code updates or verification against the new driver.
- Update devDependency '@git.zone/tstest' from ^2.8.1 to ^3.1.3 — test tooling updated.
## 2025-11-17 - 6.0.0 - BREAKING CHANGE(decorators)
Migrate to TC39 Stage 3 decorators and refactor decorator metadata handling; update class initialization, lucene adapter fixes and docs
- Switch all decorators to TC39 Stage 3 signatures and metadata usage (use context.metadata and context.addInitializer) — affects svDb, globalSvDb, searchable, unI, index, Collection and managed.
@@ -24,24 +163,27 @@ Migrate to TC39 Stage 3 decorators and refactor decorator metadata handling; upd
- Clean up project memory/config files related to the previous decorator approach and Deno configuration adjustments.
## 2025-11-17 - 5.16.7 - fix(classes.collection)
Improve Deno and TypeScript compatibility: Collection decorator _svDbOptions forwarding and config cleanup
- Collection decorator: capture original constructor and forward _svDbOptions to ensure property decorator options (serialize/deserialize) remain accessible in Deno environments.
Improve Deno and TypeScript compatibility: Collection decorator \_svDbOptions forwarding and config cleanup
- Collection decorator: capture original constructor and forward \_svDbOptions to ensure property decorator options (serialize/deserialize) remain accessible in Deno environments.
- Collection decorator: keep instance getter defined on prototype for Deno compatibility (no behavior change, clarifies forwarding logic).
- Build/config: removed experimentalDecorators and useDefineForClassFields from deno.json and tsconfig.json to avoid Deno/TS build issues and rely on default compilation settings.
## 2025-11-17 - 5.16.6 - fix(classes)
Add Deno compatibility, prototype-safe decorators and safe collection accessor; bump a few deps
- Add deno.json to enable experimentalDecorators and target ES2022/DOM for Deno builds.
- Introduce getCollectionSafe() on SmartDataDbDoc and use it for save/update/delete/findOne to avoid runtime errors when instance 'collection' is not present.
- Change several instance properties (globalSaveableProperties, uniqueIndexes, regularIndexes, saveableProperties) to 'declare' so decorator-set prototype properties are not shadowed (Deno compatibility).
- Enhance @Collection decorator: capture original constructor/prototype for Deno, define prototype getter for collection on decorated class, attach docCtor for searchableFields, and forward _svDbOptions to the original constructor to preserve serializer metadata.
- Enhance @Collection decorator: capture original constructor/prototype for Deno, define prototype getter for collection on decorated class, attach docCtor for searchableFields, and forward \_svDbOptions to the original constructor to preserve serializer metadata.
- Improve text/search index handling by relying on docCtor.searchableFields and guarding text index creation.
- Bump dependencies/devDependencies: @push.rocks/smartmongo -> ^2.0.14, @git.zone/tsbuild -> ^2.7.1, @git.zone/tstest -> ^2.8.1.
- These are non-breaking runtime compatibility and developer-experience fixes; intended as a patch release.
## 2025-11-16 - 5.16.5 - fix(watcher)
Update dependencies, tooling and watcher import; add .serena cache ignore
- Bump runtime dependencies: @push.rocks/smartlog 3.1.8 → 3.1.10, @push.rocks/smartstring 4.0.15 → 4.1.0, @push.rocks/taskbuffer 3.1.7 → 3.4.0, @tsclass/tsclass 9.2.0 → 9.3.0, mongodb 6.18.0 → 6.20.0
@@ -50,6 +192,7 @@ Update dependencies, tooling and watcher import; add .serena cache ignore
- Add .serena/.gitignore to ignore /cache
## 2025-08-18 - 5.16.4 - fix(classes.doc (convertFilterForMongoDb))
Improve filter conversion: handle logical operators, merge operator objects, add nested filter tests and docs, and fix test script
- Fix package.json test script: remove stray dot in tstest --verbose argument to ensure tests run correctly
@@ -60,6 +203,7 @@ Improve filter conversion: handle logical operators, merge operator objects, add
- Expand README filtering section with detailed examples for basic filtering, deep nested filters, comparison operators, array operations, logical and element operators, and advanced patterns
## 2025-08-18 - 5.16.3 - fix(docs)
Add local Claude settings and remove outdated codex.md
- Added .claude/settings.local.json to store local Claude/assistant permissions and configuration.
@@ -67,6 +211,7 @@ Add local Claude settings and remove outdated codex.md
- No runtime/library code changes; documentation/configuration-only update, bump patch version.
## 2025-08-18 - 5.16.2 - fix(readme)
Update README: clarify examples, expand search/cursor/docs and add local Claude settings
- Refined README wording and structure: clearer Quick Start, improved examples and developer-focused phrasing
@@ -75,6 +220,7 @@ Update README: clarify examples, expand search/cursor/docs and add local Claude
- Added .claude/settings.local.json to provide local assistant/CI permission configuration
## 2025-08-12 - 5.16.1 - fix(core)
Improve error handling and logging; enhance search query sanitization; update dependency versions and documentation
- Replaced console.log and console.warn with structured logger.log calls throughout the core modules
@@ -85,6 +231,7 @@ Improve error handling and logging; enhance search query sanitization; update de
- Updated README with improved instructions, feature highlights, and quick start sections
## 2025-04-25 - 5.16.0 - feat(watcher)
Enhance change stream watchers with buffering and EventEmitter support; update dependency versions
- Bumped smartmongo from ^2.0.11 to ^2.0.12 and smartrx from ^3.0.7 to ^3.0.10
@@ -93,6 +240,7 @@ Enhance change stream watchers with buffering and EventEmitter support; update d
- Modified SmartdataDbWatcher to extend EventEmitter and support event notifications
## 2025-04-24 - 5.15.1 - fix(cursor)
Improve cursor usage documentation and refactor getCursor API to support native cursor modifiers
- Updated examples in readme.md to demonstrate manual iteration using cursor.next() and proper cursor closing.
@@ -100,6 +248,7 @@ Improve cursor usage documentation and refactor getCursor API to support native
- Added new tests in test/test.cursor.ts to verify cursor operations, including limits, sorting, and skipping.
## 2025-04-24 - 5.15.0 - feat(svDb)
Enhance svDb decorator to support custom serialization and deserialization options
- Added an optional options parameter to the svDb decorator to accept serialize/deserialize functions
@@ -107,6 +256,7 @@ Enhance svDb decorator to support custom serialization and deserialization optio
- Updated createSavableObject to use custom serialization when available
## 2025-04-23 - 5.14.1 - fix(db operations)
Update transaction API to consistently pass optional session parameters across database operations
- Revised transaction support in readme to use startSession without await and showcased session usage in getInstance and save calls
@@ -115,14 +265,16 @@ Update transaction API to consistently pass optional session parameters across d
- Improved overall consistency of transactional APIs across the library
## 2025-04-23 - 5.14.0 - feat(doc)
Implement support for beforeSave, afterSave, beforeDelete, and afterDelete lifecycle hooks in document save and delete operations to allow custom logic execution during these critical moments.
- Calls beforeSave hook if defined before performing insert or update.
- Calls afterSave hook after a document is saved.
- Calls beforeDelete hook before deletion and afterDelete hook afterward.
- Ensures _updatedAt timestamp is refreshed during save operations.
- Ensures \_updatedAt timestamp is refreshed during save operations.
## 2025-04-22 - 5.13.1 - fix(search)
Improve search query parsing for implicit AND queries by preserving quoted substrings and better handling free terms, quoted phrases, and field:value tokens.
- Replace previous implicit AND logic with tokenization that preserves quoted substrings
@@ -130,6 +282,7 @@ Improve search query parsing for implicit AND queries by preserving quoted subst
- Ensure errors are thrown for non-searchable fields in field-specific queries
## 2025-04-22 - 5.13.0 - feat(search)
Improve search query handling and update documentation
- Added 'codex.md' providing a high-level project overview and detailed search API documentation.
@@ -138,12 +291,14 @@ Improve search query handling and update documentation
- Updated tests in test/test.search.ts to cover new combined query scenarios and ensure robust behavior.
## 2025-04-22 - 5.12.2 - fix(search)
Fix handling of quoted wildcard patterns in field-specific search queries and add tests for location-based wildcard phrase searches
- Strip surrounding quotes from wildcard patterns in field queries to correctly transform them to regex
- Introduce new tests in test/test.search.ts to validate exact quoted and unquoted wildcard searches on a location field
## 2025-04-22 - 5.12.1 - fix(search)
Improve implicit AND logic for mixed free term and field queries in search and enhance wildcard field handling.
- Updated regex for field:value parsing to capture full value with wildcards.
@@ -152,6 +307,7 @@ Improve implicit AND logic for mixed free term and field queries in search and e
- Extended tests to cover combined free term and wildcard field searches, including error cases.
## 2025-04-22 - 5.12.0 - feat(doc/search)
Enhance search functionality with filter and validate options for advanced query control
- Added 'filter' option to merge additional MongoDB query constraints in search
@@ -160,6 +316,7 @@ Enhance search functionality with filter and validate options for advanced query
- Updated tests to cover new search scenarios and fallback mechanisms
## 2025-04-22 - 5.11.4 - fix(search)
Implement implicit AND logic for mixed simple term and field:value queries in search
- Added a new branch to detect and handle search queries that mix field:value pairs with plain terms without explicit operators
@@ -167,6 +324,7 @@ Implement implicit AND logic for mixed simple term and field:value queries in se
- Ensures proper parsing and improved robustness of search filters
## 2025-04-22 - 5.11.3 - fix(lucene adapter and search tests)
Improve range query parsing in Lucene adapter and expand search test coverage
- Added a new 'testSearch' script in package.json to run search tests.
@@ -175,12 +333,14 @@ Improve range query parsing in Lucene adapter and expand search test coverage
- Fixed token validation in the parseRange method of the Lucene adapter to ensure proper error handling.
## 2025-04-21 - 5.11.2 - fix(readme)
Update readme to clarify usage of searchable fields retrieval
- Replaced getSearchableFields('Product') with Product.getSearchableFields()
- Updated documentation to reference the static method Class.getSearchableFields()
## 2025-04-21 - 5.11.1 - fix(doc)
Refactor searchable fields API and improve collection registration.
- Removed the standalone getSearchableFields utility in favor of a static method on document classes.
@@ -189,11 +349,13 @@ Refactor searchable fields API and improve collection registration.
- Added try/catch in test cleanup to gracefully handle dropDatabase errors.
## 2025-04-21 - 5.11.0 - feat(ts/classes.lucene.adapter)
Expose luceneWildcardToRegex method to allow external usage and enhance regex transformation capabilities.
- Changed luceneWildcardToRegex from private to public in ts/classes.lucene.adapter.ts.
## 2025-04-21 - 5.10.0 - feat(search)
Improve search functionality: update documentation, refine Lucene query transformation, and add advanced search tests
- Updated readme.md with detailed Lucenestyle search examples and use cases
@@ -202,6 +364,7 @@ Improve search functionality: update documentation, refine Lucene query transfor
- Added new advanced search tests covering boolean operators, grouping, quoted phrases, and wildcard queries
## 2025-04-18 - 5.9.2 - fix(documentation)
Update search API documentation to replace deprecated searchWithLucene examples with the unified search(query) API and clarify its behavior.
- Replaced 'searchWithLucene' examples with 'search(query)' in the README.
@@ -209,24 +372,28 @@ Update search API documentation to replace deprecated searchWithLucene examples
- Clarified guidelines for creating MongoDB text indexes on searchable fields for optimized search performance.
## 2025-04-18 - 5.9.1 - fix(search)
Refactor search tests to use unified search API and update text index type casting
- Replaced all calls from searchWithLucene with search in test/search tests
- Updated text index specification in the collection class to use proper type casting
## 2025-04-18 - 5.9.0 - feat(collections/search)
Improve text index creation and search fallback mechanisms in collections and document search methods
- Auto-create a compound text index on all searchable fields in SmartdataCollection with a one-time flag to prevent duplicate index creation.
- Refine the search method in SmartDataDbDoc to support exact field matches and safe regex fallback for non-Lucene queries.
## 2025-04-17 - 5.8.4 - fix(core)
Update commit metadata with no functional code changes
- Commit info and documentation refreshed
- No code or test changes detected in the diff
## 2025-04-17 - 5.8.3 - fix(readme)
Improve readme documentation on data models and connection management
- Clarify that data models use @Collection, @unI, @svDb, @index, and @searchable decorators
@@ -235,12 +402,14 @@ Improve readme documentation on data models and connection management
- Revise license section to reference the MIT License without including additional legal details
## 2025-04-14 - 5.8.2 - fix(classes.doc.ts)
Ensure collection initialization before creating a cursor in getCursorExtended
- Added 'await collection.init()' to guarantee that the MongoDB collection is initialized before using the cursor
- Prevents potential runtime errors when accessing collection.mongoDbCollection
## 2025-04-14 - 5.8.1 - fix(cursor, doc)
Add explicit return types and casts to SmartdataDbCursor methods and update getCursorExtended signature in SmartDataDbDoc.
- Specify Promise<T> as return type for next() in SmartdataDbCursor and cast return value to T.
@@ -248,12 +417,14 @@ Add explicit return types and casts to SmartdataDbCursor methods and update getC
- Update getCursorExtended to return Promise<SmartdataDbCursor<T>> for clearer type safety.
## 2025-04-14 - 5.8.0 - feat(cursor)
Add toArray method to SmartdataDbCursor to convert raw MongoDB documents into initialized class instances
- Introduced asynchronous toArray method in SmartdataDbCursor which retrieves all documents from the MongoDB cursor
- Maps each native document to a SmartDataDbDoc instance using createInstanceFromMongoDbNativeDoc for consistent API usage
## 2025-04-14 - 5.7.0 - feat(SmartDataDbDoc)
Add extended cursor method getCursorExtended for flexible cursor modifications
- Introduces getCursorExtended in classes.doc.ts to allow modifier functions for MongoDB cursors
@@ -261,6 +432,7 @@ Add extended cursor method getCursorExtended for flexible cursor modifications
- Enhances querying capabilities by enabling customized cursor transformations
## 2025-04-07 - 5.6.0 - feat(indexing)
Add support for regular index creation in documents and collections
- Implement new index decorator in classes.doc.ts to mark properties with regular indexing options
@@ -268,6 +440,7 @@ Add support for regular index creation in documents and collections
- Enhance document structure to store and utilize regular index configurations
## 2025-04-06 - 5.5.1 - fix(ci & formatting)
Minor fixes: update CI workflow image and npmci package references, adjust package.json and readme URLs, and apply consistent code formatting.
- Update image and repo URL in Gitea workflows from GitLab to code.foss.global
@@ -277,6 +450,7 @@ Minor fixes: update CI workflow image and npmci package references, adjust packa
- Minor update to .gitignore custom section label
## 2025-04-06 - 5.5.0 - feat(search)
Enhance search functionality with robust Lucene query transformation and reliable fallback mechanisms
- Improve Lucene adapter to properly structure $or queries for term, phrase, wildcard, and fuzzy search
@@ -284,15 +458,17 @@ Enhance search functionality with robust Lucene query transformation and reliabl
- Update readme and tests with extensive examples for @searchable fields and Lucene-based queries
## 2025-04-06 - 5.4.0 - feat(core)
Refactor file structure and update dependency versions
- Renamed files and modules from 'smartdata.classes.*' to 'classes.*' and adjusted corresponding import paths.
- Renamed files and modules from 'smartdata.classes._' to 'classes._' and adjusted corresponding import paths.
- Updated dependency versions: '@push.rocks/smartmongo' to ^2.0.11, '@tsclass/tsclass' to ^8.2.0, and 'mongodb' to ^6.15.0.
- Renamed dev dependency packages from '@gitzone/...' to '@git.zone/...' and updated '@push.rocks/tapbundle' and '@types/node'.
- Fixed YAML workflow command: replaced 'pnpm install -g @gitzone/tsdoc' with 'pnpm install -g @git.zone/tsdoc'.
- Added package manager configuration and pnpm-workspace.yaml for built dependencies.
## 2025-03-10 - 5.3.0 - feat(docs)
Enhance documentation with updated installation instructions and comprehensive usage examples covering advanced features such as deep queries, automatic indexing, and distributed coordination.
- Added pnpm installation command
@@ -302,11 +478,13 @@ Enhance documentation with updated installation instructions and comprehensive u
- Included detailed examples for transactions, deep object queries, and document lifecycle hooks
## 2025-02-03 - 5.2.12 - fix(documentation)
Remove license badge from README
- Removed the license badge from the README file, ensuring compliance with branding guidelines.
## 2025-02-03 - 5.2.11 - fix(documentation)
Updated project documentation for accuracy and added advanced feature details
- Added details for EasyStore, Distributed Coordination, and Real-time Data Watching features.
@@ -314,158 +492,188 @@ Updated project documentation for accuracy and added advanced feature details
- Re-organized advanced usage section to showcase additional features separately.
## 2024-09-05 - 5.2.10 - fix(smartdata.classes.doc)
Fix issue with array handling in convertFilterForMongoDb function
- Corrected the logic to properly handle array filters in the convertFilterForMongoDb function to avoid incorrect assignments.
## 2024-09-05 - 5.2.9 - fix(smartdata.classes.doc)
Fixed issue with convertFilterForMongoDb to handle array operators.
- Updated the convertFilterForMongoDb function in smartdata.classes.doc.ts to properly handle array operators like $in and $all.
## 2024-09-05 - 5.2.8 - fix(smartdata.classes.doc)
Fix key handling in convertFilterForMongoDb function
- Fixed an issue in convertFilterForMongoDb that allowed keys with dots which could cause errors.
## 2024-09-05 - 5.2.7 - fix(core)
Fixed issue with handling filter keys containing dots in smartdata.classes.doc.ts
- Fixed an error in the convertFilterForMongoDb function which previously threw an error when keys contained dots.
## 2024-06-18 - 5.2.6 - Chore
Maintenance Release
- Release version 5.2.6
## 2024-05-31 - 5.2.2 - Bug Fixes
Fixes and Maintenance
- Fixed issue where `_createdAt` and `_updatedAt` registered saveableProperties for all document types
## 2024-04-15 - 5.1.2 - New Feature
Enhancements and Bug Fixes
- Added static `.getCount({})` method to `SmartDataDbDoc`
- Changed fields `_createdAt` and `_updatedAt` to ISO format
## 2024-04-14 - 5.0.43 - New Feature
New Feature Addition
- Added default `_createdAt` and `_updatedAt` fields, fixes #1
## 2024-03-30 - 5.0.41 - Bug Fixes
Improvements and Fixes
- Improved `tsconfig.json` for ES Module use
## 2023-07-10 - 5.0.20 - Chore
Organizational Changes
- Switched to new org scheme
## 2023-07-21 - 5.0.21 to 5.0.26 - Fixes
Multiple Fix Releases
- Various core updates and bug fixes
## 2023-07-21 - 5.0.20 - Chore
Organizational Changes
- Switch to the new org scheme
## 2023-06-25 - 5.0.14 to 5.0.19 - Fixes
Multiple Fix Releases
- Various core updates and bug fixes
## 2022-05-17 - 5.0.0 - Major Update
Breaking Changes
- Switched to ESM
## 2022-05-18 - 5.0.2 - Bug Fixes
Bug Fixes
- The `watcher.changeSubject` now emits the correct type into observer functions
## 2022-05-17 - 5.0.1 - Chore
Testing Improvements
- Tests now use `@pushrocks/smartmongo` backed by `wiredTiger`
## 2022-05-17 to 2022-11-08 - 5.0.8 to 5.0.10
Multiple Fix Releases
- Various core updates and bug fixes
## 2021-11-12 - 4.0.17 to 4.0.20
Multiple Fix Releases
- Various core updates and bug fixes
## 2021-09-17 - 4.0.10 to 4.0.16
Multiple Fix Releases
- Various core updates and bug fixes
## 2021-06-09 - 4.0.1 to 4.0.9
Multiple Fix Releases
- Various core updates and bug fixes
## 2021-06-06 - 4.0.0 - Major Update
Major Release
- Maintenance and core updates
## 2021-05-17 - 3.1.56 - Chore
Maintenance Release
- Release version 3.1.56
## 2020-09-09 - 3.1.44 to 3.1.52
Multiple Fix Releases
- Various core updates and bug fixes
## 2020-06-12 - 3.1.26 to 3.1.28
Multiple Fix Releases
- Various core updates and bug fixes
## 2020-02-18 - 3.1.23 to 3.1.25
Multiple Fix Releases
- Various core updates and bug fixes
## 2019-09-11 - 3.1.20 to 3.1.22
Multiple Fix Releases
- Various core updates and bug fixes
## 2018-07-10 - 3.0.5 - New Feature
Added Feature
- Added custom unique indexes to `SmartdataDoc`
## 2018-07-08 - 3.0.1 - Chore
Dependencies Update
- Updated mongodb dependencies
## 2018-07-08 - 3.0.0 - Major Update
Refactor and Cleanup
- Cleaned project structure
## 2018-01-16 - 2.0.7 - Breaking Change
Big Changes
- Switched to `@pushrocks` scope and moved from `rethinkdb` to `mongodb`
## 2018-01-12 - 2.0.0 - Major Release
Core Updates
- Updated CI configurations

5651
deno.lock generated

File diff suppressed because it is too large Load Diff

21
license Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Task Venture Capital GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,15 +1,16 @@
{
"name": "@push.rocks/smartdata",
"version": "7.0.1",
"version": "7.1.3",
"private": false,
"description": "An advanced library for NoSQL data organization and manipulation using TypeScript with support for MongoDB, data validation, collections, and custom data types.",
"main": "dist_ts/index.js",
"typings": "dist_ts/index.d.ts",
"exports": {
".": "./dist_ts/index.js"
},
"type": "module",
"scripts": {
"test": "tstest test/ --verbose --logfile --timeout 120",
"testSearch": "tsx test/test.search.ts",
"build": "tsbuild --web --allowimplicitany",
"build": "tsbuild tsfolders",
"buildDocs": "tsdoc"
},
"repository": {
@@ -23,26 +24,25 @@
},
"homepage": "https://code.foss.global/push.rocks/smartdata#readme",
"dependencies": {
"@push.rocks/lik": "^6.2.2",
"@push.rocks/smartdelay": "^3.0.1",
"@push.rocks/smartlog": "^3.1.10",
"@push.rocks/smartmongo": "^2.0.14",
"@push.rocks/smartpromise": "^4.0.2",
"@push.rocks/lik": "^6.4.0",
"@push.rocks/smartdelay": "^3.0.5",
"@push.rocks/smartlog": "^3.2.1",
"@push.rocks/smartmongo": "^5.1.0",
"@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smartrx": "^3.0.10",
"@push.rocks/smartstring": "^4.1.0",
"@push.rocks/smarttime": "^4.0.6",
"@push.rocks/smartunique": "^3.0.8",
"@push.rocks/taskbuffer": "^3.4.0",
"@tsclass/tsclass": "^9.3.0",
"mongodb": "^7.0.0"
"@push.rocks/smarttime": "^4.2.3",
"@push.rocks/smartunique": "^3.0.9",
"@push.rocks/taskbuffer": "^8.0.2",
"@tsclass/tsclass": "^9.5.0",
"mongodb": "^7.1.1"
},
"devDependencies": {
"@git.zone/tsbuild": "^3.1.1",
"@git.zone/tsrun": "^2.0.0",
"@git.zone/tstest": "^3.1.3",
"@git.zone/tsbuild": "^4.4.0",
"@git.zone/tsrun": "^2.0.2",
"@git.zone/tstest": "^3.6.0",
"@push.rocks/qenv": "^6.1.3",
"@push.rocks/tapbundle": "^6.0.3",
"@types/node": "^22.15.2"
"@types/node": "^25.5.0"
},
"files": [
"ts/**/*",
@@ -53,7 +53,7 @@
"dist_ts_web/**/*",
"assets/**/*",
"cli.js",
"npmextra.json",
".smartconfig.json",
"readme.md"
],
"browserslist": [

6604
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +0,0 @@
onlyBuiltDependencies:
- esbuild
- mongodb-memory-server
- puppeteer

View File

@@ -1,80 +1,29 @@
# Project Memory - Smartdata
## TC39 Decorator Migration (v6.0.0) - ✅ COMPLETED
## TC39 Decorator Pattern
### Final Status: All Tests Passing (157/157)
Migration successfully completed on 2025-11-17.
### What Changed:
- ✅ Removed `experimentalDecorators` from tsconfig.json
- ✅ Refactored all 7 decorators to TC39 Stage 3 syntax
- 5 property decorators: @globalSvDb, @svDb, @unI, @index, @searchable
- 2 class decorators: @Collection, @managed
- ✅ Implemented context.metadata pattern for shared decorator state
- ✅ All tests passing across Node.js and Deno runtimes
### Critical Discovery: TC39 Metadata Access Pattern
**THE KEY INSIGHT**: In TC39 decorators, metadata is NOT accessed via `constructor[Symbol.metadata]`. Instead:
- **Field decorators**: Write to `context.metadata`
- **Class decorators**: Read from `context.metadata` (same shared object!)
- The `context.metadata` object is shared between all decorators on the same class
- Attempting to write to `constructor[Symbol.metadata]` throws: "Cannot assign to read only property"
- **Class decorators**: Read from `context.metadata` (same shared object)
- `Symbol.metadata` on constructors is read-only (managed by runtime)
- Field decorators run before class decorators (guaranteed order)
- `declare` keyword for instance properties accessed via prototype getters (avoids ES2022 shadowing)
### Implementation Pattern:
```typescript
// Field decorator - stores metadata
export function svDb() {
return (value: undefined, context: ClassFieldDecoratorContext) => {
const metadata = context.metadata as ISmartdataDecoratorMetadata;
if (!metadata.saveableProperties) {
metadata.saveableProperties = [];
}
metadata.saveableProperties.push(String(context.name));
};
}
### Runtime Compatibility
// Class decorator - reads metadata and initializes prototype
export function Collection(dbArg: SmartdataDb) {
return function(value: Function, context: ClassDecoratorContext) => {
const metadata = context.metadata as ISmartdataDecoratorMetadata;
if (metadata?.saveableProperties) {
decoratedClass.prototype.saveableProperties = [...metadata.saveableProperties];
}
return decoratedClass;
};
}
```
- ✅ Node.js v20+ / v25+: Full TC39 support
- ✅ Deno v2.x: Full TC39 support
- ❌ Bun: No TC39 support (uses legacy decorators only)
### Runtime Compatibility:
-**Node.js v23.8.0**: Full TC39 support
-**Deno v2.5.4**: Full TC39 support
-**Bun v1.3.0**: No TC39 support (uses legacy decorators only)
- Removed "+bun" from test filenames to skip Bun tests
## Build Configuration (v7.1.0+)
### Key Technical Notes:
1. **Metadata Initialization Timing**: Class decorators run AFTER field decorators, allowing them to read accumulated metadata and initialize prototypes before any instances are created
2. **Prototype vs Instance Properties**: Properties set on prototype are accessible via `this.propertyName` in instances
3. **TypeScript Lib Support**: TypeScript 5.9.3 includes built-in decorator types (no custom lib configuration needed)
4. **Interface Naming**: Used `ISmartdataDecoratorMetadata` extending `DecoratorMetadataObject` for type safety
- **Build tool**: `@git.zone/tsbuild` v4 with `tsbuild tsfolders`
- **tsconfig.json**: Includes `"types": ["node"]` since tsbuild v4 defaults to DOM+ESNext lib only
- **Strict mode**: tsbuild v4 enables strict checks; properties use `!` definite assignment or `declare`
- **Test imports**: Use `@git.zone/tstest/tapbundle` (NOT `@push.rocks/tapbundle`)
- **Config file**: `.smartconfig.json` (renamed from `npmextra.json`)
### Files Modified:
- ts/classes.doc.ts (property decorators + metadata interface)
- ts/classes.collection.ts (class decorators + prototype initialization)
- tsconfig.json (removed experimentalDecorators flag)
- test/*.ts (renamed files to remove "+bun" suffix)
## Dependencies (v7.1.0+)
### Test Results:
All 157 tests passing across 10 test files:
- test.cursor.ts: 7/7
- test.deno.ts: 11/11 (queries working correctly!)
- test.search.advanced.ts: 41/41
- test.typescript.ts: 4/4
- test.watch.ts: 5/5
- And 5 more test files
### Migration Learnings for Future Reference:
1. `context.metadata` is the ONLY way to share state between decorators
2. Class decorators must initialize prototypes from metadata immediately
3. `Symbol.metadata` on constructors is read-only (managed by runtime)
4. Field decorators run before class decorators (guaranteed order)
5. TypeScript 5.2+ has built-in TC39 decorator support
- `@push.rocks/taskbuffer` v8: distributedCoordination API at `taskbuffer.distributedCoordination.*`
- `@push.rocks/smartmongo` v5: API compatible (`createAndStart`, `getMongoDescriptor`, `stop`, `stopAndDumpToDir`)
- `mongodb` v7.1: ChangeStream requires `Document` constraint, use `any` for generic watcher

899
readme.md

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js';
import * as smartdata from '../ts/index.js';

View File

@@ -1,6 +1,6 @@
// TODO: Decorator support during testing for bun and deno in @git.zone/tstest
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js';

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import * as smartmongo from '@push.rocks/smartmongo';
import type * as taskbuffer from '@push.rocks/taskbuffer';

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js';

View File

@@ -1,6 +1,6 @@
// TODO: Decorator support during testing for bun and deno in @git.zone/tstest
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js';

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import * as smartmongo from '@push.rocks/smartmongo';
import * as smartdata from '../ts/index.js';
import { searchable } from '../ts/classes.doc.js';

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js';

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js';

View File

@@ -1,4 +1,4 @@
import { tap, expect } from '@push.rocks/tapbundle';
import { tap, expect } from '@git.zone/tstest/tapbundle';
import { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js';

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartdata',
version: '7.0.1',
version: '7.1.3',
description: 'An advanced library for NoSQL data organization and manipulation using TypeScript with support for MongoDB, data validation, collections, and custom data types.'
}

View File

@@ -21,6 +21,42 @@ export type TDelayed<TDelayedArg> = () => TDelayedArg;
const collectionFactory = new CollectionFactory();
/**
* Initialize prototype and constructor properties from TC39 decorator metadata.
* Shared by both Collection and managed decorators.
*/
function initializeDecoratorMetadata(
constructor: { new (...args: any[]): any; prototype: any },
metadata: any
): void {
if (!metadata) return;
const proto = constructor.prototype;
const ctor = constructor as any;
// Prototype properties (instance-level)
if (metadata.globalSaveableProperties && !proto.globalSaveableProperties) {
proto.globalSaveableProperties = [...metadata.globalSaveableProperties];
}
if (metadata.saveableProperties && !proto.saveableProperties) {
proto.saveableProperties = [...metadata.saveableProperties];
}
if (metadata.uniqueIndexes && !proto.uniqueIndexes) {
proto.uniqueIndexes = [...metadata.uniqueIndexes];
}
if (metadata.regularIndexes && !proto.regularIndexes) {
proto.regularIndexes = [...metadata.regularIndexes];
}
// Constructor properties (static-level)
if (metadata.searchableFields && !Array.isArray(ctor.searchableFields)) {
ctor.searchableFields = [...metadata.searchableFields];
}
if (metadata._svDbOptions && !ctor._svDbOptions) {
ctor._svDbOptions = { ...metadata._svDbOptions };
}
}
/**
* This is a decorator that will tell the decorated class what dbTable to use
* @param dbArg
@@ -31,9 +67,7 @@ export function Collection(dbArg: SmartdataDb | TDelayed<SmartdataDb>) {
throw new Error('Collection can only decorate classes');
}
// Capture original constructor for _svDbOptions forwarding
const originalConstructor = value as any;
const constructor = value as { new (...args: any[]): any };
const constructor = value as { new (...args: any[]): any } & { className?: string };
const getCollection = () => {
if (!(dbArg instanceof SmartdataDb)) {
@@ -41,79 +75,31 @@ export function Collection(dbArg: SmartdataDb | TDelayed<SmartdataDb>) {
}
const coll = collectionFactory.getCollection(constructor.name, dbArg);
// Attach document constructor for searchableFields lookup
if (!(coll as any).docCtor) {
(coll as any).docCtor = decoratedClass;
if (coll && !(coll as any).docCtor) {
(coll as any).docCtor = constructor;
}
return coll;
};
const decoratedClass = class extends constructor {
public static className = constructor.name;
public static get collection() {
return getCollection();
}
public get collection() {
return getCollection();
}
};
// Add static className property directly on the constructor
(constructor as any).className = constructor.name;
// Ensure instance getter works in Deno by defining it on the prototype
Object.defineProperty(decoratedClass.prototype, 'collection', {
// Define collection getter on constructor (static access)
Object.defineProperty(constructor, 'collection', {
get: getCollection,
enumerable: false,
configurable: true
});
// Deno compatibility note: Property decorators set properties on the prototype.
// Since we removed instance property declarations from SmartDataDbDoc,
// the decorator-set prototype properties are now accessible without shadowing.
// No manual forwarding needed - natural prototype inheritance works!
// Point to original constructor's _svDbOptions
Object.defineProperty(decoratedClass, '_svDbOptions', {
get() { return originalConstructor._svDbOptions; },
set(value) { originalConstructor._svDbOptions = value; },
// Define collection getter on prototype (instance access)
Object.defineProperty(constructor.prototype, 'collection', {
get: getCollection,
enumerable: false,
configurable: true
});
// Initialize prototype properties from context.metadata (TC39 decorator metadata)
// This ensures prototype properties are available before any instance is created
const metadata = context.metadata as any;
if (metadata) {
const proto = decoratedClass.prototype;
// Initialize globalSaveableProperties
if (metadata.globalSaveableProperties && !proto.globalSaveableProperties) {
proto.globalSaveableProperties = [...metadata.globalSaveableProperties];
}
// Initialize saveableProperties
if (metadata.saveableProperties && !proto.saveableProperties) {
proto.saveableProperties = [...metadata.saveableProperties];
}
// Initialize uniqueIndexes
if (metadata.uniqueIndexes && !proto.uniqueIndexes) {
proto.uniqueIndexes = [...metadata.uniqueIndexes];
}
// Initialize regularIndexes
if (metadata.regularIndexes && !proto.regularIndexes) {
proto.regularIndexes = [...metadata.regularIndexes];
}
// Initialize searchableFields on constructor (not prototype)
if (metadata.searchableFields && !Array.isArray((decoratedClass as any).searchableFields)) {
(decoratedClass as any).searchableFields = [...metadata.searchableFields];
}
// Initialize _svDbOptions from metadata
if (metadata._svDbOptions && !originalConstructor._svDbOptions) {
originalConstructor._svDbOptions = { ...metadata._svDbOptions };
}
}
return decoratedClass as any;
initializeDecoratorMetadata(constructor, context.metadata);
return constructor as any;
};
}
@@ -136,97 +122,46 @@ export function managed<TManager extends IManager>(managerArg?: TManager | TDela
throw new Error('managed can only decorate classes');
}
const constructor = value as { new (...args: any[]): any };
const constructor = value as { new (...args: any[]): any } & { className?: string };
(constructor as any).className = constructor.name;
const decoratedClass = class extends constructor {
public static className = constructor.name;
public static get collection() {
let dbArg: SmartdataDb;
if (!managerArg) {
dbArg = this.prototype.defaultManager.db;
} else if (managerArg['db']) {
dbArg = (managerArg as TManager).db;
} else {
dbArg = (managerArg as TDelayed<TManager>)().db;
}
return collectionFactory.getCollection(constructor.name, dbArg);
}
public get collection() {
let dbArg: SmartdataDb;
if (!managerArg) {
//console.log(this.defaultManager.db);
//process.exit(0)
dbArg = this.defaultManager.db;
} else if (managerArg['db']) {
dbArg = (managerArg as TManager).db;
} else {
dbArg = (managerArg as TDelayed<TManager>)().db;
}
return collectionFactory.getCollection(constructor.name, dbArg);
}
public static get manager() {
let manager: TManager;
if (!managerArg) {
manager = this.prototype.defaultManager;
} else if (managerArg['db']) {
manager = managerArg as TManager;
} else {
manager = (managerArg as TDelayed<TManager>)();
}
return manager;
}
public get manager() {
let manager: TManager;
if (!managerArg) {
manager = this.defaultManager;
} else if (managerArg['db']) {
manager = managerArg as TManager;
} else {
manager = (managerArg as TDelayed<TManager>)();
}
return manager;
}
// Resolution helpers (capture managerArg via closure)
const getManager = (defaultManagerFn: () => TManager): TManager => {
if (!managerArg) return defaultManagerFn();
if (managerArg['db']) return managerArg as TManager;
return (managerArg as TDelayed<TManager>)();
};
// Initialize prototype properties from context.metadata (TC39 decorator metadata)
// This ensures prototype properties are available before any instance is created
const originalConstructor = value as any;
const metadata = context.metadata as any;
if (metadata) {
const proto = decoratedClass.prototype;
const getDb = (defaultManagerFn: () => TManager): SmartdataDb => {
return getManager(defaultManagerFn).db;
};
// Initialize globalSaveableProperties
if (metadata.globalSaveableProperties && !proto.globalSaveableProperties) {
proto.globalSaveableProperties = [...metadata.globalSaveableProperties];
}
// Static getters
Object.defineProperty(constructor, 'collection', {
get(this: any) { return collectionFactory.getCollection(constructor.name, getDb(() => this.prototype.defaultManager)); },
enumerable: false,
configurable: true
});
Object.defineProperty(constructor, 'manager', {
get(this: any) { return getManager(() => this.prototype.defaultManager); },
enumerable: false,
configurable: true
});
// Initialize saveableProperties
if (metadata.saveableProperties && !proto.saveableProperties) {
proto.saveableProperties = [...metadata.saveableProperties];
}
// Instance getters
Object.defineProperty(constructor.prototype, 'collection', {
get(this: any) { return collectionFactory.getCollection(constructor.name, getDb(() => this.defaultManager)); },
enumerable: false,
configurable: true
});
Object.defineProperty(constructor.prototype, 'manager', {
get(this: any) { return getManager(() => this.defaultManager); },
enumerable: false,
configurable: true
});
// Initialize uniqueIndexes
if (metadata.uniqueIndexes && !proto.uniqueIndexes) {
proto.uniqueIndexes = [...metadata.uniqueIndexes];
}
// Initialize regularIndexes
if (metadata.regularIndexes && !proto.regularIndexes) {
proto.regularIndexes = [...metadata.regularIndexes];
}
// Initialize searchableFields on constructor (not prototype)
if (metadata.searchableFields && !Array.isArray((decoratedClass as any).searchableFields)) {
(decoratedClass as any).searchableFields = [...metadata.searchableFields];
}
// Initialize _svDbOptions from metadata
if (metadata._svDbOptions && !originalConstructor._svDbOptions) {
originalConstructor._svDbOptions = { ...metadata._svDbOptions };
}
}
return decoratedClass as any;
initializeDecoratorMetadata(constructor, context.metadata);
return constructor as any;
};
}
@@ -239,8 +174,8 @@ export class SmartdataCollection<T> {
/**
* the collection that is used
*/
public mongoDbCollection: plugins.mongodb.Collection;
public objectValidation: IDocValidationFunc<T> = null;
public mongoDbCollection!: plugins.mongodb.Collection;
public objectValidation: IDocValidationFunc<T> | null = null;
public collectionName: string;
public smartdataDb: SmartdataDb;
public uniqueIndexes: string[] = [];
@@ -395,7 +330,7 @@ export class SmartdataCollection<T> {
);
const smartdataWatcher = new SmartdataDbWatcher(
changeStream,
smartdataDbDocArg,
smartdataDbDocArg!,
{ bufferTimeMs },
);
await smartdataWatcher.readyDeferred.promise;
@@ -418,7 +353,7 @@ export class SmartdataCollection<T> {
this.createRegularIndexes(dbDocArg.regularIndexes);
}
const saveableObject = await dbDocArg.createSavableObject();
const saveableObject = await dbDocArg.createSavableObject() as any;
const result = await this.mongoDbCollection.insertOne(saveableObject, { session: opts?.session });
return result;
}
@@ -433,7 +368,7 @@ export class SmartdataCollection<T> {
await this.init();
await this.checkDoc(dbDocArg);
const identifiableObject = await dbDocArg.createIdentifiableObject();
const saveableObject = await dbDocArg.createSavableObject();
const saveableObject = await dbDocArg.createSavableObject() as any;
const updateableObject: any = {};
for (const key of Object.keys(saveableObject)) {
if (identifiableObject[key]) {

View File

@@ -6,13 +6,8 @@ export class CollectionFactory {
public collections: { [key: string]: SmartdataCollection<any> } = {};
public getCollection = (nameArg: string, dbArg: SmartdataDb): SmartdataCollection<any> => {
if (!this.collections[nameArg]) {
this.collections[nameArg] = (() => {
if (dbArg instanceof SmartdataDb) {
// tslint:disable-next-line: no-string-literal
return new SmartdataCollection(nameArg, dbArg);
}
})();
if (!this.collections[nameArg] && dbArg instanceof SmartdataDb) {
this.collections[nameArg] = new SmartdataCollection(nameArg, dbArg);
}
return this.collections[nameArg];
};

View File

@@ -12,8 +12,8 @@ export type TConnectionStatus = 'initial' | 'disconnected' | 'connected' | 'fail
export class SmartdataDb {
smartdataOptions: plugins.tsclass.database.IMongoDescriptor;
mongoDbClient: plugins.mongodb.MongoClient;
mongoDb: plugins.mongodb.Db;
mongoDbClient!: plugins.mongodb.MongoClient;
mongoDb!: plugins.mongodb.Db;
status: TConnectionStatus;
statusConnectedDeferred = plugins.smartpromise.defer();
smartdataCollectionMap = new plugins.lik.ObjectMap<SmartdataCollection<any>>();
@@ -51,13 +51,14 @@ export class SmartdataDb {
.replace('<user>', encodedUser)
.replace('<PASSWORD>', encodedPass)
.replace('<password>', encodedPass)
.replace('<DBNAME>', this.smartdataOptions.mongoDbName)
.replace('<dbname>', this.smartdataOptions.mongoDbName);
.replace('<DBNAME>', this.smartdataOptions.mongoDbName || '')
.replace('<dbname>', this.smartdataOptions.mongoDbName || '');
const clientOptions: plugins.mongodb.MongoClientOptions = {
maxPoolSize: (this.smartdataOptions as any).maxPoolSize ?? 100,
maxIdleTimeMS: (this.smartdataOptions as any).maxIdleTimeMS ?? 300000, // 5 minutes default
serverSelectionTimeoutMS: (this.smartdataOptions as any).serverSelectionTimeoutMS ?? 30000,
socketTimeoutMS: (this.smartdataOptions as any).socketTimeoutMS ?? 30000, // 30 seconds default — prevents hung operations from holding connections
retryWrites: true,
};
@@ -69,7 +70,7 @@ export class SmartdataDb {
} catch (error) {
this.status = 'disconnected';
this.statusConnectedDeferred.reject(error);
logger.log('error', `Failed to connect to database ${this.smartdataOptions.mongoDbName}: ${error.message}`);
logger.log('error', `Failed to connect to database ${this.smartdataOptions.mongoDbName}: ${(error as Error).message}`);
throw error;
}
}

View File

@@ -9,10 +9,10 @@ import { logger } from './logging.js';
export class DistributedClass extends SmartDataDbDoc<DistributedClass, DistributedClass> {
// INSTANCE
@unI()
public id: string;
public id!: string;
@svDb()
public data: {
public data!: {
status: 'initializing' | 'bidding' | 'settled' | 'stopped';
biddingShortcode?: string;
biddingStartTime?: number;
@@ -40,8 +40,8 @@ export class SmartdataDistributedCoordinator extends plugins.taskbuffer.distribu
public readyPromise: Promise<any>;
public db: SmartdataDb;
private asyncExecutionStack = new plugins.lik.AsyncExecutionStack();
public ownInstance: DistributedClass;
public distributedWatcher: SmartdataDbWatcher<DistributedClass>;
public ownInstance!: DistributedClass;
public distributedWatcher!: SmartdataDbWatcher<DistributedClass>;
constructor(dbArg: SmartdataDb) {
super();
@@ -163,8 +163,8 @@ export class SmartdataDistributedCoordinator extends plugins.taskbuffer.distribu
} else if (
(await DistributedClass.getInstances({})).find((instanceArg) => {
return instanceArg.data.status === 'bidding' &&
instanceArg.data.biddingStartTime <= Date.now() - 4000 &&
instanceArg.data.biddingStartTime >= Date.now() - 30000;
instanceArg.data.biddingStartTime! <= Date.now() - 4000 &&
instanceArg.data.biddingStartTime! >= Date.now() - 30000;
})
) {
logger.log('info', 'too late to the bidding party... waiting for next round.');
@@ -191,7 +191,7 @@ export class SmartdataDistributedCoordinator extends plugins.taskbuffer.distribu
logger.log('info', `found ${biddingInstances.length} bidding instances...`);
this.ownInstance.data.elected = true;
for (const biddingInstance of biddingInstances) {
if (biddingInstance.data.biddingShortcode < this.ownInstance.data.biddingShortcode) {
if (biddingInstance.data.biddingShortcode! < this.ownInstance.data.biddingShortcode!) {
this.ownInstance.data.elected = false;
}
}
@@ -270,7 +270,7 @@ export class SmartdataDistributedCoordinator extends plugins.taskbuffer.distribu
});
if (!result) {
logger.log('warn', 'no result found for task request...');
return null;
return null as any;
}
return result;
}

View File

@@ -51,8 +51,6 @@ export function globalSvDb() {
}
metadata.globalSaveableProperties.push(String(context.name));
logger.log('debug', `called globalSvDb() on metadata for property ${String(context.name)}`);
// Use addInitializer to ensure prototype arrays are set up once
context.addInitializer(function(this: any) {
const proto = this.constructor.prototype;
@@ -61,7 +59,6 @@ export function globalSvDb() {
if (metadata && metadata.globalSaveableProperties && !proto.globalSaveableProperties) {
// Initialize prototype array from metadata (runs once per class)
proto.globalSaveableProperties = [...metadata.globalSaveableProperties];
logger.log('debug', `initialized globalSaveableProperties with ${proto.globalSaveableProperties.length} properties`);
}
});
};
@@ -103,8 +100,6 @@ export function svDb(options?: SvDbOptions) {
metadata._svDbOptions[propName] = options;
}
logger.log('debug', `called svDb() on metadata for property ${propName}`);
// Use addInitializer to ensure prototype arrays are set up once
context.addInitializer(function(this: any) {
const proto = this.constructor.prototype;
@@ -114,7 +109,6 @@ export function svDb(options?: SvDbOptions) {
if (metadata && metadata.saveableProperties && !proto.saveableProperties) {
// Initialize prototype array from metadata (runs once per class)
proto.saveableProperties = [...metadata.saveableProperties];
logger.log('debug', `initialized saveableProperties with ${proto.saveableProperties.length} properties`);
}
// Initialize svDbOptions from metadata
@@ -187,8 +181,6 @@ export function unI() {
metadata.saveableProperties.push(propName);
}
logger.log('debug', `called unI on metadata for property ${propName}`);
// Use addInitializer to ensure prototype arrays are set up once
context.addInitializer(function(this: any) {
const proto = this.constructor.prototype;
@@ -196,7 +188,6 @@ export function unI() {
if (metadata && metadata.uniqueIndexes && !proto.uniqueIndexes) {
proto.uniqueIndexes = [...metadata.uniqueIndexes];
logger.log('debug', `initialized uniqueIndexes with ${proto.uniqueIndexes.length} properties`);
}
if (metadata && metadata.saveableProperties && !proto.saveableProperties) {
@@ -246,8 +237,6 @@ export function index(options?: IIndexOptions) {
metadata.saveableProperties.push(propName);
}
logger.log('debug', `called index() on metadata for property ${propName}`);
// Use addInitializer to ensure prototype arrays are set up once
context.addInitializer(function(this: any) {
const proto = this.constructor.prototype;
@@ -255,7 +244,6 @@ export function index(options?: IIndexOptions) {
if (metadata && metadata.regularIndexes && !proto.regularIndexes) {
proto.regularIndexes = [...metadata.regularIndexes];
logger.log('debug', `initialized regularIndexes with ${proto.regularIndexes.length} indexes`);
}
if (metadata && metadata.saveableProperties && !proto.saveableProperties) {
@@ -448,10 +436,10 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
* the collection object an Doc belongs to
*/
public static collection: SmartdataCollection<any>;
public collection: SmartdataCollection<any>;
declare public collection: SmartdataCollection<any>;
public static defaultManager;
public static manager;
public manager: TManager;
declare public manager: TManager;
/**
* Helper to get collection with fallback to static for Deno compatibility
@@ -494,7 +482,7 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
convertFilterForMongoDb(filterArg),
{ session: opts?.session },
);
const returnArray = [];
const returnArray: T[] = [];
for (const foundDoc of foundDocs) {
const newInstance: T = (this as any).createInstanceFromMongoDbNativeDoc(foundDoc);
returnArray.push(newInstance);
@@ -522,7 +510,7 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
const newInstance: T = (this as any).createInstanceFromMongoDbNativeDoc(foundDoc);
return newInstance;
} else {
return null;
return null as any;
}
}
@@ -845,12 +833,12 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
/**
* name
*/
public name: string;
public name!: string;
/**
* primary id in the database
*/
public dbDocUniqueId: string;
public dbDocUniqueId!: string;
/**
* class constructor
@@ -910,7 +898,7 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
* also store any referenced objects to DB
* better for data consistency
*/
public saveDeep(savedMapArg: plugins.lik.ObjectMap<SmartDataDbDoc<any, any>> = null) {
public saveDeep(savedMapArg?: plugins.lik.ObjectMap<SmartDataDbDoc<any, any>>) {
if (!savedMapArg) {
savedMapArg = new plugins.lik.ObjectMap<SmartDataDbDoc<any, any>>();
}

View File

@@ -15,19 +15,19 @@ export class EasyStore<T> {
@Collection(() => this.smartdataDbRef)
class SmartdataEasyStore extends SmartDataDbDoc<SmartdataEasyStore, SmartdataEasyStore> {
@unI()
public nameId: string;
public nameId!: string;
@svDb()
public ephemeral: {
public ephemeral!: {
activated: boolean;
timeout: number;
};
@svDb()
lastEdit: number;
lastEdit!: number;
@svDb()
public data: Partial<T>;
public data!: Partial<T>;
}
return SmartdataEasyStore;
})();
@@ -37,7 +37,7 @@ export class EasyStore<T> {
this.nameId = nameIdArg;
}
private easyStorePromise: Promise<InstanceType<typeof this.easyStoreClass>>;
private easyStorePromise!: Promise<InstanceType<typeof this.easyStoreClass>>;
private async getEasyStore(): Promise<InstanceType<typeof this.easyStoreClass>> {
if (this.easyStorePromise) {
return this.easyStorePromise;

View File

@@ -536,7 +536,7 @@ export class LuceneToMongoTransformer {
const searchTerm = rightQuery.$text.$search.replace(/"/g, '');
// Determine the fields to apply the negation to
const notConditions = [];
const notConditions: any[] = [];
for (const field in leftQuery) {
if (field !== '$or' && field !== '$and') {

View File

@@ -13,7 +13,7 @@ export class SmartdataDbWatcher<T = any> extends EventEmitter {
public readyDeferred = plugins.smartpromise.defer();
// INSTANCE
private changeStream: plugins.mongodb.ChangeStream<T>;
private changeStream: plugins.mongodb.ChangeStream<any>;
private rawSubject: plugins.smartrx.rxjs.Subject<T>;
/** Emits change documents (or arrays of documents if buffered) */
public changeSubject: any;
@@ -23,7 +23,7 @@ export class SmartdataDbWatcher<T = any> extends EventEmitter {
* @param opts.bufferTimeMs optional milliseconds to buffer events via RxJS
*/
constructor(
changeStreamArg: plugins.mongodb.ChangeStream<T>,
changeStreamArg: plugins.mongodb.ChangeStream<any>,
smartdataDbDocArg: typeof SmartDataDbDoc,
opts?: { bufferTimeMs?: number },
) {
@@ -37,14 +37,14 @@ export class SmartdataDbWatcher<T = any> extends EventEmitter {
}
this.changeStream = changeStreamArg;
this.changeStream.on('change', async (item: any) => {
let docInstance: T = null;
let docInstance: T | null = null;
if (item.fullDocument) {
docInstance = smartdataDbDocArg.createInstanceFromMongoDbNativeDoc(
item.fullDocument
) as any as T;
}
// Notify subscribers
this.rawSubject.next(docInstance);
this.rawSubject.next(docInstance as T);
this.emit('change', docInstance);
});
// Signal readiness after one tick

View File

@@ -1,3 +1,6 @@
// Polyfill must be imported first - ES modules hoist exports before code runs
import './shim.js';
export * from './classes.db.js';
export * from './classes.collection.js';
export * from './classes.doc.js';

6
ts/shim.ts Normal file
View File

@@ -0,0 +1,6 @@
/**
* Polyfill for Symbol.metadata required by TC39 Stage 3 decorators.
* Must be imported before any decorator code loads.
* @see https://github.com/tc39/proposal-decorator-metadata
*/
(Symbol as any).metadata ??= Symbol.for('Symbol.metadata');

View File

@@ -5,10 +5,9 @@
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"baseUrl": ".",
"paths": {}
"types": [
"node"
]
},
"exclude": [
"dist_*/**/*.d.ts"
]
}
"exclude": ["dist_*/**/*.d.ts"]
}