fix(build): update build and test tooling configuration, migrate project config to .smartconfig.json, and align TypeScript typings

This commit is contained in:
2026-03-24 19:44:49 +00:00
parent 27c1500db5
commit 03431535d7
29 changed files with 2210 additions and 1669 deletions

View File

@@ -7,7 +7,7 @@ on:
env: env:
IMAGE: code.foss.global/host.today/ht-docker-node:npmci 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_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}

View File

@@ -7,7 +7,7 @@ on:
env: env:
IMAGE: code.foss.global/host.today/ht-docker-node:npmci 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_NPM: ${{secrets.NPMCI_TOKEN_NPM}}
NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}} NPMCI_TOKEN_NPM2: ${{secrets.NPMCI_TOKEN_NPM2}}
NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}} NPMCI_GIT_GITHUBTOKEN: ${{secrets.NPMCI_GIT_GITHUBTOKEN}}

8
.gitignore vendored
View File

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

View File

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

View File

@@ -1,6 +1,16 @@
# Changelog # Changelog
## 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) ## 2026-02-26 - 7.1.0 - feat(config)
normalize npmextra.json to namespaced keys and add CI/release configuration 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). - Replaced legacy keys (npmdocker, npmci, gitzone, tsdoc) with namespaced package keys (@git.zone/cli, @git.zone/tsdoc, @git.zone/tsdocker, @ship.zone/szci).
@@ -10,6 +20,7 @@ normalize npmextra.json to namespaced keys and add CI/release configuration
- Removed old top-level entries to consolidate tooling configuration under scoped keys. - Removed old top-level entries to consolidate tooling configuration under scoped keys.
## 2026-02-26 - 7.0.16 - fix(mongodb) ## 2026-02-26 - 7.0.16 - fix(mongodb)
set default socketTimeoutMS to 30000ms in MongoClient options to prevent hung operations from holding connections 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 - Adds socketTimeoutMS: 30000 to MongoClient clientOptions in ts/classes.db.ts
@@ -17,20 +28,23 @@ set default socketTimeoutMS to 30000ms in MongoClient options to prevent hung op
- Non-breaking change (defaults only) - Non-breaking change (defaults only)
## 2025-12-01 - 7.0.15 - fix(classes.doc) ## 2025-12-01 - 7.0.15 - fix(classes.doc)
Avoid emitting instance fields for collection and manager to preserve decorator-defined prototype getters 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. - 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. - 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) ## 2025-11-28 - 7.0.14 - fix(classes.collection)
Centralize TC39 decorator metadata initialization and use context.metadata in class decorators 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 - Add initializeDecoratorMetadata helper to initialize prototype and constructor properties from TC39 decorator metadata
- Refactor Collection and managed decorators to call initializeDecoratorMetadata with context.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 - 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 - Ensure consistent initialization of saveableProperties, globalSaveableProperties, uniqueIndexes, regularIndexes, searchableFields and \_svDbOptions
## 2025-11-28 - 7.0.13 - fix(classes.doc) ## 2025-11-28 - 7.0.13 - fix(classes.doc)
Remove noisy debug logging from decorators and serialization logic Remove noisy debug logging from decorators and serialization logic
- Removed debug logger calls from globalSvDb decorator initialization - Removed debug logger calls from globalSvDb decorator initialization
@@ -39,20 +53,23 @@ Remove noisy debug logging from decorators and serialization logic
- Removed debug logging in createSavableObject to reduce console noise; no functional changes - Removed debug logging in createSavableObject to reduce console noise; no functional changes
## 2025-11-28 - 7.0.12 - fix(collection) ## 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 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 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 - 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 - 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 - 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) ## 2025-11-28 - 7.0.9 - fix(classes.collection)
Fix closure bug in Collection decorator by defining collection getter on original constructor and prototype 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. - 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). - 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) ## 2025-11-28 - 7.0.8 - fix(classes.collection)
Fix closure issue in managed decorator so Class.collection/instance.collection resolve correctly 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. - 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.
@@ -60,6 +77,7 @@ Fix closure issue in managed decorator so Class.collection/instance.collection r
- Getters are defined as non-enumerable and configurable to preserve compatibility with existing consumers. - Getters are defined as non-enumerable and configurable to preserve compatibility with existing consumers.
## 2025-11-28 - 7.0.7 - fix(decorators) ## 2025-11-28 - 7.0.7 - fix(decorators)
Fix decorator metadata initialization and Lucene query transformation 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). - Ensure TC39 decorator metadata is used to initialize prototype properties so decorators work reliably across runtimes (context.metadata / Symbol.metadata shim imported early).
@@ -68,12 +86,14 @@ Fix decorator metadata initialization and Lucene query transformation
- Improve collection initialization to auto-create compound text indexes from searchableFields and ensure index creation is idempotent. - 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) ## 2025-11-28 - 7.0.6 - fix(classes.collection)
Guard against missing collection before attaching document constructor in Collection decorator 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). - 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. - Prevents a potential TypeError when `collectionFactory.getCollection` returns null/undefined during decorator initialization.
## 2025-11-28 - 7.0.5 - fix(package) ## 2025-11-28 - 7.0.5 - fix(package)
Add package exports entry and remove legacy main/typings fields 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. - Added an "exports" entry in package.json mapping "." to ./dist_ts/index.js to declare the package's ESM entrypoint.
@@ -81,6 +101,7 @@ Add package exports entry and remove legacy main/typings fields
- Improves Node/module resolution and modern bundler compatibility by using the package exports field. - Improves Node/module resolution and modern bundler compatibility by using the package exports field.
## 2025-11-28 - 7.0.4 - fix(decorators) ## 2025-11-28 - 7.0.4 - fix(decorators)
Add Symbol.metadata polyfill and import it at entry to ensure decorator metadata is available 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). - Add ts/shim.ts: defines Symbol.metadata when missing (polyfill for TC39 Stage 3 decorator metadata).
@@ -88,11 +109,13 @@ Add Symbol.metadata polyfill and import it at entry to ensure decorator metadata
- Prevents runtime errors when decorators rely on Symbol.metadata and improves compatibility across runtimes/environments. - Prevents runtime errors when decorators rely on Symbol.metadata and improves compatibility across runtimes/environments.
## 2025-11-28 - 7.0.3 - fix(build) ## 2025-11-28 - 7.0.3 - fix(build)
Bump devDependency @git.zone/tsbuild to ^3.1.2 Bump devDependency @git.zone/tsbuild to ^3.1.2
- Updated @git.zone/tsbuild in devDependencies from ^3.1.1 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) ## 2025-11-28 - 7.0.2 - fix(collectionfactory)
Simplify CollectionFactory.getCollection: remove unnecessary IIFE and instantiate collection only when dbArg is SmartdataDb Simplify CollectionFactory.getCollection: remove unnecessary IIFE and instantiate collection only when dbArg is SmartdataDb
- Remove redundant IIFE wrapper in getCollection for improved readability - Remove redundant IIFE wrapper in getCollection for improved readability
@@ -100,18 +123,21 @@ Simplify CollectionFactory.getCollection: remove unnecessary IIFE and instantiat
- Avoid assigning undefined to the collections map by guarding instantiation and returning existing collection - Avoid assigning undefined to the collections map by guarding instantiation and returning existing collection
## 2025-11-27 - 7.0.1 - fix(build) ## 2025-11-27 - 7.0.1 - fix(build)
Update build tooling and TypeScript compilation target Update build tooling and TypeScript compilation target
- Bump devDependency @git.zone/tsbuild from ^3.1.0 to ^3.1.1. - 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). - Update tsconfig.json compiler target from ES2022 to ES2024 (affects emitted JS language level).
## 2025-11-27 - 7.0.0 - BREAKING CHANGE(mongodb) ## 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 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. - 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. - 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) ## 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 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. - 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.
@@ -123,24 +149,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. - 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) ## 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). - 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. - 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) ## 2025-11-17 - 5.16.6 - fix(classes)
Add Deno compatibility, prototype-safe decorators and safe collection accessor; bump a few deps 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. - 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. - 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). - 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. - 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. - 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. - These are non-breaking runtime compatibility and developer-experience fixes; intended as a patch release.
## 2025-11-16 - 5.16.5 - fix(watcher) ## 2025-11-16 - 5.16.5 - fix(watcher)
Update dependencies, tooling and watcher import; add .serena cache ignore 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 - 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
@@ -149,6 +178,7 @@ Update dependencies, tooling and watcher import; add .serena cache ignore
- Add .serena/.gitignore to ignore /cache - Add .serena/.gitignore to ignore /cache
## 2025-08-18 - 5.16.4 - fix(classes.doc (convertFilterForMongoDb)) ## 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 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 - Fix package.json test script: remove stray dot in tstest --verbose argument to ensure tests run correctly
@@ -159,6 +189,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 - 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) ## 2025-08-18 - 5.16.3 - fix(docs)
Add local Claude settings and remove outdated codex.md Add local Claude settings and remove outdated codex.md
- Added .claude/settings.local.json to store local Claude/assistant permissions and configuration. - Added .claude/settings.local.json to store local Claude/assistant permissions and configuration.
@@ -166,6 +197,7 @@ Add local Claude settings and remove outdated codex.md
- No runtime/library code changes; documentation/configuration-only update, bump patch version. - No runtime/library code changes; documentation/configuration-only update, bump patch version.
## 2025-08-18 - 5.16.2 - fix(readme) ## 2025-08-18 - 5.16.2 - fix(readme)
Update README: clarify examples, expand search/cursor/docs and add local Claude settings 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 - Refined README wording and structure: clearer Quick Start, improved examples and developer-focused phrasing
@@ -174,6 +206,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 - Added .claude/settings.local.json to provide local assistant/CI permission configuration
## 2025-08-12 - 5.16.1 - fix(core) ## 2025-08-12 - 5.16.1 - fix(core)
Improve error handling and logging; enhance search query sanitization; update dependency versions and documentation 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 - Replaced console.log and console.warn with structured logger.log calls throughout the core modules
@@ -184,6 +217,7 @@ Improve error handling and logging; enhance search query sanitization; update de
- Updated README with improved instructions, feature highlights, and quick start sections - Updated README with improved instructions, feature highlights, and quick start sections
## 2025-04-25 - 5.16.0 - feat(watcher) ## 2025-04-25 - 5.16.0 - feat(watcher)
Enhance change stream watchers with buffering and EventEmitter support; update dependency versions 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 - Bumped smartmongo from ^2.0.11 to ^2.0.12 and smartrx from ^3.0.7 to ^3.0.10
@@ -192,6 +226,7 @@ Enhance change stream watchers with buffering and EventEmitter support; update d
- Modified SmartdataDbWatcher to extend EventEmitter and support event notifications - Modified SmartdataDbWatcher to extend EventEmitter and support event notifications
## 2025-04-24 - 5.15.1 - fix(cursor) ## 2025-04-24 - 5.15.1 - fix(cursor)
Improve cursor usage documentation and refactor getCursor API to support native cursor modifiers 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. - Updated examples in readme.md to demonstrate manual iteration using cursor.next() and proper cursor closing.
@@ -199,6 +234,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. - 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) ## 2025-04-24 - 5.15.0 - feat(svDb)
Enhance svDb decorator to support custom serialization and deserialization options Enhance svDb decorator to support custom serialization and deserialization options
- Added an optional options parameter to the svDb decorator to accept serialize/deserialize functions - Added an optional options parameter to the svDb decorator to accept serialize/deserialize functions
@@ -206,6 +242,7 @@ Enhance svDb decorator to support custom serialization and deserialization optio
- Updated createSavableObject to use custom serialization when available - Updated createSavableObject to use custom serialization when available
## 2025-04-23 - 5.14.1 - fix(db operations) ## 2025-04-23 - 5.14.1 - fix(db operations)
Update transaction API to consistently pass optional session parameters across database 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 - Revised transaction support in readme to use startSession without await and showcased session usage in getInstance and save calls
@@ -214,14 +251,16 @@ Update transaction API to consistently pass optional session parameters across d
- Improved overall consistency of transactional APIs across the library - Improved overall consistency of transactional APIs across the library
## 2025-04-23 - 5.14.0 - feat(doc) ## 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. 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 beforeSave hook if defined before performing insert or update.
- Calls afterSave hook after a document is saved. - Calls afterSave hook after a document is saved.
- Calls beforeDelete hook before deletion and afterDelete hook afterward. - 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) ## 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. 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 - Replace previous implicit AND logic with tokenization that preserves quoted substrings
@@ -229,6 +268,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 - Ensure errors are thrown for non-searchable fields in field-specific queries
## 2025-04-22 - 5.13.0 - feat(search) ## 2025-04-22 - 5.13.0 - feat(search)
Improve search query handling and update documentation Improve search query handling and update documentation
- Added 'codex.md' providing a high-level project overview and detailed search API documentation. - Added 'codex.md' providing a high-level project overview and detailed search API documentation.
@@ -237,12 +277,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. - 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) ## 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 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 - 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 - 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) ## 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. 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. - Updated regex for field:value parsing to capture full value with wildcards.
@@ -251,6 +293,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. - Extended tests to cover combined free term and wildcard field searches, including error cases.
## 2025-04-22 - 5.12.0 - feat(doc/search) ## 2025-04-22 - 5.12.0 - feat(doc/search)
Enhance search functionality with filter and validate options for advanced query control Enhance search functionality with filter and validate options for advanced query control
- Added 'filter' option to merge additional MongoDB query constraints in search - Added 'filter' option to merge additional MongoDB query constraints in search
@@ -259,6 +302,7 @@ Enhance search functionality with filter and validate options for advanced query
- Updated tests to cover new search scenarios and fallback mechanisms - Updated tests to cover new search scenarios and fallback mechanisms
## 2025-04-22 - 5.11.4 - fix(search) ## 2025-04-22 - 5.11.4 - fix(search)
Implement implicit AND logic for mixed simple term and field:value queries in 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 - Added a new branch to detect and handle search queries that mix field:value pairs with plain terms without explicit operators
@@ -266,6 +310,7 @@ Implement implicit AND logic for mixed simple term and field:value queries in se
- Ensures proper parsing and improved robustness of search filters - Ensures proper parsing and improved robustness of search filters
## 2025-04-22 - 5.11.3 - fix(lucene adapter and search tests) ## 2025-04-22 - 5.11.3 - fix(lucene adapter and search tests)
Improve range query parsing in Lucene adapter and expand search test coverage Improve range query parsing in Lucene adapter and expand search test coverage
- Added a new 'testSearch' script in package.json to run search tests. - Added a new 'testSearch' script in package.json to run search tests.
@@ -274,12 +319,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. - Fixed token validation in the parseRange method of the Lucene adapter to ensure proper error handling.
## 2025-04-21 - 5.11.2 - fix(readme) ## 2025-04-21 - 5.11.2 - fix(readme)
Update readme to clarify usage of searchable fields retrieval Update readme to clarify usage of searchable fields retrieval
- Replaced getSearchableFields('Product') with Product.getSearchableFields() - Replaced getSearchableFields('Product') with Product.getSearchableFields()
- Updated documentation to reference the static method Class.getSearchableFields() - Updated documentation to reference the static method Class.getSearchableFields()
## 2025-04-21 - 5.11.1 - fix(doc) ## 2025-04-21 - 5.11.1 - fix(doc)
Refactor searchable fields API and improve collection registration. Refactor searchable fields API and improve collection registration.
- Removed the standalone getSearchableFields utility in favor of a static method on document classes. - Removed the standalone getSearchableFields utility in favor of a static method on document classes.
@@ -288,11 +335,13 @@ Refactor searchable fields API and improve collection registration.
- Added try/catch in test cleanup to gracefully handle dropDatabase errors. - Added try/catch in test cleanup to gracefully handle dropDatabase errors.
## 2025-04-21 - 5.11.0 - feat(ts/classes.lucene.adapter) ## 2025-04-21 - 5.11.0 - feat(ts/classes.lucene.adapter)
Expose luceneWildcardToRegex method to allow external usage and enhance regex transformation capabilities. Expose luceneWildcardToRegex method to allow external usage and enhance regex transformation capabilities.
- Changed luceneWildcardToRegex from private to public in ts/classes.lucene.adapter.ts. - Changed luceneWildcardToRegex from private to public in ts/classes.lucene.adapter.ts.
## 2025-04-21 - 5.10.0 - feat(search) ## 2025-04-21 - 5.10.0 - feat(search)
Improve search functionality: update documentation, refine Lucene query transformation, and add advanced search tests 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 - Updated readme.md with detailed Lucenestyle search examples and use cases
@@ -301,6 +350,7 @@ Improve search functionality: update documentation, refine Lucene query transfor
- Added new advanced search tests covering boolean operators, grouping, quoted phrases, and wildcard queries - Added new advanced search tests covering boolean operators, grouping, quoted phrases, and wildcard queries
## 2025-04-18 - 5.9.2 - fix(documentation) ## 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. 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. - Replaced 'searchWithLucene' examples with 'search(query)' in the README.
@@ -308,24 +358,28 @@ Update search API documentation to replace deprecated searchWithLucene examples
- Clarified guidelines for creating MongoDB text indexes on searchable fields for optimized search performance. - Clarified guidelines for creating MongoDB text indexes on searchable fields for optimized search performance.
## 2025-04-18 - 5.9.1 - fix(search) ## 2025-04-18 - 5.9.1 - fix(search)
Refactor search tests to use unified search API and update text index type casting 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 - Replaced all calls from searchWithLucene with search in test/search tests
- Updated text index specification in the collection class to use proper type casting - Updated text index specification in the collection class to use proper type casting
## 2025-04-18 - 5.9.0 - feat(collections/search) ## 2025-04-18 - 5.9.0 - feat(collections/search)
Improve text index creation and search fallback mechanisms in collections and document search methods 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. - 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. - 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) ## 2025-04-17 - 5.8.4 - fix(core)
Update commit metadata with no functional code changes Update commit metadata with no functional code changes
- Commit info and documentation refreshed - Commit info and documentation refreshed
- No code or test changes detected in the diff - No code or test changes detected in the diff
## 2025-04-17 - 5.8.3 - fix(readme) ## 2025-04-17 - 5.8.3 - fix(readme)
Improve readme documentation on data models and connection management Improve readme documentation on data models and connection management
- Clarify that data models use @Collection, @unI, @svDb, @index, and @searchable decorators - Clarify that data models use @Collection, @unI, @svDb, @index, and @searchable decorators
@@ -334,12 +388,14 @@ Improve readme documentation on data models and connection management
- Revise license section to reference the MIT License without including additional legal details - Revise license section to reference the MIT License without including additional legal details
## 2025-04-14 - 5.8.2 - fix(classes.doc.ts) ## 2025-04-14 - 5.8.2 - fix(classes.doc.ts)
Ensure collection initialization before creating a cursor in getCursorExtended 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 - Added 'await collection.init()' to guarantee that the MongoDB collection is initialized before using the cursor
- Prevents potential runtime errors when accessing collection.mongoDbCollection - Prevents potential runtime errors when accessing collection.mongoDbCollection
## 2025-04-14 - 5.8.1 - fix(cursor, doc) ## 2025-04-14 - 5.8.1 - fix(cursor, doc)
Add explicit return types and casts to SmartdataDbCursor methods and update getCursorExtended signature in SmartDataDbDoc. 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. - Specify Promise<T> as return type for next() in SmartdataDbCursor and cast return value to T.
@@ -347,12 +403,14 @@ Add explicit return types and casts to SmartdataDbCursor methods and update getC
- Update getCursorExtended to return Promise<SmartdataDbCursor<T>> for clearer type safety. - Update getCursorExtended to return Promise<SmartdataDbCursor<T>> for clearer type safety.
## 2025-04-14 - 5.8.0 - feat(cursor) ## 2025-04-14 - 5.8.0 - feat(cursor)
Add toArray method to SmartdataDbCursor to convert raw MongoDB documents into initialized class instances 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 - 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 - Maps each native document to a SmartDataDbDoc instance using createInstanceFromMongoDbNativeDoc for consistent API usage
## 2025-04-14 - 5.7.0 - feat(SmartDataDbDoc) ## 2025-04-14 - 5.7.0 - feat(SmartDataDbDoc)
Add extended cursor method getCursorExtended for flexible cursor modifications Add extended cursor method getCursorExtended for flexible cursor modifications
- Introduces getCursorExtended in classes.doc.ts to allow modifier functions for MongoDB cursors - Introduces getCursorExtended in classes.doc.ts to allow modifier functions for MongoDB cursors
@@ -360,6 +418,7 @@ Add extended cursor method getCursorExtended for flexible cursor modifications
- Enhances querying capabilities by enabling customized cursor transformations - Enhances querying capabilities by enabling customized cursor transformations
## 2025-04-07 - 5.6.0 - feat(indexing) ## 2025-04-07 - 5.6.0 - feat(indexing)
Add support for regular index creation in documents and collections 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 - Implement new index decorator in classes.doc.ts to mark properties with regular indexing options
@@ -367,6 +426,7 @@ Add support for regular index creation in documents and collections
- Enhance document structure to store and utilize regular index configurations - Enhance document structure to store and utilize regular index configurations
## 2025-04-06 - 5.5.1 - fix(ci & formatting) ## 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. 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 - Update image and repo URL in Gitea workflows from GitLab to code.foss.global
@@ -376,6 +436,7 @@ Minor fixes: update CI workflow image and npmci package references, adjust packa
- Minor update to .gitignore custom section label - Minor update to .gitignore custom section label
## 2025-04-06 - 5.5.0 - feat(search) ## 2025-04-06 - 5.5.0 - feat(search)
Enhance search functionality with robust Lucene query transformation and reliable fallback mechanisms 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 - Improve Lucene adapter to properly structure $or queries for term, phrase, wildcard, and fuzzy search
@@ -383,15 +444,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 - Update readme and tests with extensive examples for @searchable fields and Lucene-based queries
## 2025-04-06 - 5.4.0 - feat(core) ## 2025-04-06 - 5.4.0 - feat(core)
Refactor file structure and update dependency versions 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. - 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'. - 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'. - 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. - Added package manager configuration and pnpm-workspace.yaml for built dependencies.
## 2025-03-10 - 5.3.0 - feat(docs) ## 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. 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 - Added pnpm installation command
@@ -401,11 +464,13 @@ Enhance documentation with updated installation instructions and comprehensive u
- Included detailed examples for transactions, deep object queries, and document lifecycle hooks - Included detailed examples for transactions, deep object queries, and document lifecycle hooks
## 2025-02-03 - 5.2.12 - fix(documentation) ## 2025-02-03 - 5.2.12 - fix(documentation)
Remove license badge from README Remove license badge from README
- Removed the license badge from the README file, ensuring compliance with branding guidelines. - Removed the license badge from the README file, ensuring compliance with branding guidelines.
## 2025-02-03 - 5.2.11 - fix(documentation) ## 2025-02-03 - 5.2.11 - fix(documentation)
Updated project documentation for accuracy and added advanced feature details Updated project documentation for accuracy and added advanced feature details
- Added details for EasyStore, Distributed Coordination, and Real-time Data Watching features. - Added details for EasyStore, Distributed Coordination, and Real-time Data Watching features.
@@ -413,158 +478,188 @@ Updated project documentation for accuracy and added advanced feature details
- Re-organized advanced usage section to showcase additional features separately. - Re-organized advanced usage section to showcase additional features separately.
## 2024-09-05 - 5.2.10 - fix(smartdata.classes.doc) ## 2024-09-05 - 5.2.10 - fix(smartdata.classes.doc)
Fix issue with array handling in convertFilterForMongoDb function Fix issue with array handling in convertFilterForMongoDb function
- Corrected the logic to properly handle array filters in the convertFilterForMongoDb function to avoid incorrect assignments. - 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) ## 2024-09-05 - 5.2.9 - fix(smartdata.classes.doc)
Fixed issue with convertFilterForMongoDb to handle array operators. 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. - 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) ## 2024-09-05 - 5.2.8 - fix(smartdata.classes.doc)
Fix key handling in convertFilterForMongoDb function Fix key handling in convertFilterForMongoDb function
- Fixed an issue in convertFilterForMongoDb that allowed keys with dots which could cause errors. - Fixed an issue in convertFilterForMongoDb that allowed keys with dots which could cause errors.
## 2024-09-05 - 5.2.7 - fix(core) ## 2024-09-05 - 5.2.7 - fix(core)
Fixed issue with handling filter keys containing dots in smartdata.classes.doc.ts 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. - Fixed an error in the convertFilterForMongoDb function which previously threw an error when keys contained dots.
## 2024-06-18 - 5.2.6 - Chore ## 2024-06-18 - 5.2.6 - Chore
Maintenance Release Maintenance Release
- Release version 5.2.6 - Release version 5.2.6
## 2024-05-31 - 5.2.2 - Bug Fixes ## 2024-05-31 - 5.2.2 - Bug Fixes
Fixes and Maintenance Fixes and Maintenance
- Fixed issue where `_createdAt` and `_updatedAt` registered saveableProperties for all document types - Fixed issue where `_createdAt` and `_updatedAt` registered saveableProperties for all document types
## 2024-04-15 - 5.1.2 - New Feature ## 2024-04-15 - 5.1.2 - New Feature
Enhancements and Bug Fixes Enhancements and Bug Fixes
- Added static `.getCount({})` method to `SmartDataDbDoc` - Added static `.getCount({})` method to `SmartDataDbDoc`
- Changed fields `_createdAt` and `_updatedAt` to ISO format - Changed fields `_createdAt` and `_updatedAt` to ISO format
## 2024-04-14 - 5.0.43 - New Feature ## 2024-04-14 - 5.0.43 - New Feature
New Feature Addition New Feature Addition
- Added default `_createdAt` and `_updatedAt` fields, fixes #1 - Added default `_createdAt` and `_updatedAt` fields, fixes #1
## 2024-03-30 - 5.0.41 - Bug Fixes ## 2024-03-30 - 5.0.41 - Bug Fixes
Improvements and Fixes Improvements and Fixes
- Improved `tsconfig.json` for ES Module use - Improved `tsconfig.json` for ES Module use
## 2023-07-10 - 5.0.20 - Chore ## 2023-07-10 - 5.0.20 - Chore
Organizational Changes Organizational Changes
- Switched to new org scheme - Switched to new org scheme
## 2023-07-21 - 5.0.21 to 5.0.26 - Fixes ## 2023-07-21 - 5.0.21 to 5.0.26 - Fixes
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2023-07-21 - 5.0.20 - Chore ## 2023-07-21 - 5.0.20 - Chore
Organizational Changes Organizational Changes
- Switch to the new org scheme - Switch to the new org scheme
## 2023-06-25 - 5.0.14 to 5.0.19 - Fixes ## 2023-06-25 - 5.0.14 to 5.0.19 - Fixes
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2022-05-17 - 5.0.0 - Major Update ## 2022-05-17 - 5.0.0 - Major Update
Breaking Changes Breaking Changes
- Switched to ESM - Switched to ESM
## 2022-05-18 - 5.0.2 - Bug Fixes ## 2022-05-18 - 5.0.2 - Bug Fixes
Bug Fixes Bug Fixes
- The `watcher.changeSubject` now emits the correct type into observer functions - The `watcher.changeSubject` now emits the correct type into observer functions
## 2022-05-17 - 5.0.1 - Chore ## 2022-05-17 - 5.0.1 - Chore
Testing Improvements Testing Improvements
- Tests now use `@pushrocks/smartmongo` backed by `wiredTiger` - Tests now use `@pushrocks/smartmongo` backed by `wiredTiger`
## 2022-05-17 to 2022-11-08 - 5.0.8 to 5.0.10 ## 2022-05-17 to 2022-11-08 - 5.0.8 to 5.0.10
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2021-11-12 - 4.0.17 to 4.0.20 ## 2021-11-12 - 4.0.17 to 4.0.20
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2021-09-17 - 4.0.10 to 4.0.16 ## 2021-09-17 - 4.0.10 to 4.0.16
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2021-06-09 - 4.0.1 to 4.0.9 ## 2021-06-09 - 4.0.1 to 4.0.9
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2021-06-06 - 4.0.0 - Major Update ## 2021-06-06 - 4.0.0 - Major Update
Major Release Major Release
- Maintenance and core updates - Maintenance and core updates
## 2021-05-17 - 3.1.56 - Chore ## 2021-05-17 - 3.1.56 - Chore
Maintenance Release Maintenance Release
- Release version 3.1.56 - Release version 3.1.56
## 2020-09-09 - 3.1.44 to 3.1.52 ## 2020-09-09 - 3.1.44 to 3.1.52
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2020-06-12 - 3.1.26 to 3.1.28 ## 2020-06-12 - 3.1.26 to 3.1.28
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2020-02-18 - 3.1.23 to 3.1.25 ## 2020-02-18 - 3.1.23 to 3.1.25
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2019-09-11 - 3.1.20 to 3.1.22 ## 2019-09-11 - 3.1.20 to 3.1.22
Multiple Fix Releases Multiple Fix Releases
- Various core updates and bug fixes - Various core updates and bug fixes
## 2018-07-10 - 3.0.5 - New Feature ## 2018-07-10 - 3.0.5 - New Feature
Added Feature Added Feature
- Added custom unique indexes to `SmartdataDoc` - Added custom unique indexes to `SmartdataDoc`
## 2018-07-08 - 3.0.1 - Chore ## 2018-07-08 - 3.0.1 - Chore
Dependencies Update Dependencies Update
- Updated mongodb dependencies - Updated mongodb dependencies
## 2018-07-08 - 3.0.0 - Major Update ## 2018-07-08 - 3.0.0 - Major Update
Refactor and Cleanup Refactor and Cleanup
- Cleaned project structure - Cleaned project structure
## 2018-01-16 - 2.0.7 - Breaking Change ## 2018-01-16 - 2.0.7 - Breaking Change
Big Changes Big Changes
- Switched to `@pushrocks` scope and moved from `rethinkdb` to `mongodb` - Switched to `@pushrocks` scope and moved from `rethinkdb` to `mongodb`
## 2018-01-12 - 2.0.0 - Major Release ## 2018-01-12 - 2.0.0 - Major Release
Core Updates Core Updates
- Updated CI configurations - Updated CI configurations

View File

@@ -10,7 +10,7 @@
"scripts": { "scripts": {
"test": "tstest test/ --verbose --logfile --timeout 120", "test": "tstest test/ --verbose --logfile --timeout 120",
"testSearch": "tsx test/test.search.ts", "testSearch": "tsx test/test.search.ts",
"build": "tsbuild --web --allowimplicitany", "build": "tsbuild tsfolders",
"buildDocs": "tsdoc" "buildDocs": "tsdoc"
}, },
"repository": { "repository": {
@@ -24,25 +24,24 @@
}, },
"homepage": "https://code.foss.global/push.rocks/smartdata#readme", "homepage": "https://code.foss.global/push.rocks/smartdata#readme",
"dependencies": { "dependencies": {
"@push.rocks/lik": "^6.2.2", "@push.rocks/lik": "^6.4.0",
"@push.rocks/smartdelay": "^3.0.1", "@push.rocks/smartdelay": "^3.0.5",
"@push.rocks/smartlog": "^3.1.10", "@push.rocks/smartlog": "^3.2.1",
"@push.rocks/smartmongo": "^2.0.14", "@push.rocks/smartmongo": "^5.1.0",
"@push.rocks/smartpromise": "^4.0.2", "@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smartrx": "^3.0.10", "@push.rocks/smartrx": "^3.0.10",
"@push.rocks/smartstring": "^4.1.0", "@push.rocks/smartstring": "^4.1.0",
"@push.rocks/smarttime": "^4.0.6", "@push.rocks/smarttime": "^4.2.3",
"@push.rocks/smartunique": "^3.0.8", "@push.rocks/smartunique": "^3.0.9",
"@push.rocks/taskbuffer": "^3.4.0", "@push.rocks/taskbuffer": "^8.0.2",
"@tsclass/tsclass": "^9.3.0", "@tsclass/tsclass": "^9.5.0",
"mongodb": "^7.0.0" "mongodb": "^7.1.1"
}, },
"devDependencies": { "devDependencies": {
"@git.zone/tsbuild": "^3.1.2", "@git.zone/tsbuild": "^4.4.0",
"@git.zone/tsrun": "^2.0.0", "@git.zone/tsrun": "^2.0.1",
"@git.zone/tstest": "^3.1.3", "@git.zone/tstest": "^3.5.1",
"@push.rocks/qenv": "^6.1.3", "@push.rocks/qenv": "^6.1.3",
"@push.rocks/tapbundle": "^6.0.3",
"@types/node": "^22.15.2" "@types/node": "^22.15.2"
}, },
"files": [ "files": [
@@ -54,7 +53,7 @@
"dist_ts_web/**/*", "dist_ts_web/**/*",
"assets/**/*", "assets/**/*",
"cli.js", "cli.js",
"npmextra.json", ".smartconfig.json",
"readme.md" "readme.md"
], ],
"browserslist": [ "browserslist": [

3384
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

@@ -3,9 +3,11 @@
## TC39 Decorator Migration (v6.0.0) - ✅ COMPLETED ## TC39 Decorator Migration (v6.0.0) - ✅ COMPLETED
### Final Status: All Tests Passing (157/157) ### Final Status: All Tests Passing (157/157)
Migration successfully completed on 2025-11-17. Migration successfully completed on 2025-11-17.
### What Changed: ### What Changed:
- ✅ Removed `experimentalDecorators` from tsconfig.json - ✅ Removed `experimentalDecorators` from tsconfig.json
- ✅ Refactored all 7 decorators to TC39 Stage 3 syntax - ✅ Refactored all 7 decorators to TC39 Stage 3 syntax
- 5 property decorators: @globalSvDb, @svDb, @unI, @index, @searchable - 5 property decorators: @globalSvDb, @svDb, @unI, @index, @searchable
@@ -14,13 +16,16 @@ Migration successfully completed on 2025-11-17.
- ✅ All tests passing across Node.js and Deno runtimes - ✅ All tests passing across Node.js and Deno runtimes
### Critical Discovery: TC39 Metadata Access Pattern ### Critical Discovery: TC39 Metadata Access Pattern
**THE KEY INSIGHT**: In TC39 decorators, metadata is NOT accessed via `constructor[Symbol.metadata]`. Instead: **THE KEY INSIGHT**: In TC39 decorators, metadata is NOT accessed via `constructor[Symbol.metadata]`. Instead:
- **Field decorators**: Write to `context.metadata` - **Field decorators**: Write to `context.metadata`
- **Class decorators**: Read from `context.metadata` (same shared object!) - **Class decorators**: Read from `context.metadata` (same shared object!)
- The `context.metadata` object is shared between all decorators on the same class - 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" - Attempting to write to `constructor[Symbol.metadata]` throws: "Cannot assign to read only property"
### Implementation Pattern: ### Implementation Pattern:
```typescript ```typescript
// Field decorator - stores metadata // Field decorator - stores metadata
export function svDb() { export function svDb() {
@@ -46,25 +51,30 @@ export function Collection(dbArg: SmartdataDb) {
``` ```
### Runtime Compatibility: ### Runtime Compatibility:
-**Node.js v23.8.0**: Full TC39 support -**Node.js v23.8.0**: Full TC39 support
-**Deno v2.5.4**: Full TC39 support -**Deno v2.5.4**: Full TC39 support
-**Bun v1.3.0**: No TC39 support (uses legacy decorators only) -**Bun v1.3.0**: No TC39 support (uses legacy decorators only)
- Removed "+bun" from test filenames to skip Bun tests - Removed "+bun" from test filenames to skip Bun tests
### Key Technical Notes: ### 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 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 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) 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 4. **Interface Naming**: Used `ISmartdataDecoratorMetadata` extending `DecoratorMetadataObject` for type safety
### Files Modified: ### Files Modified:
- ts/classes.doc.ts (property decorators + metadata interface) - ts/classes.doc.ts (property decorators + metadata interface)
- ts/classes.collection.ts (class decorators + prototype initialization) - ts/classes.collection.ts (class decorators + prototype initialization)
- tsconfig.json (removed experimentalDecorators flag) - tsconfig.json (removed experimentalDecorators flag)
- test/*.ts (renamed files to remove "+bun" suffix) - test/\*.ts (renamed files to remove "+bun" suffix)
### Test Results: ### Test Results:
All 157 tests passing across 10 test files: All 157 tests passing across 10 test files:
- test.cursor.ts: 7/7 - test.cursor.ts: 7/7
- test.deno.ts: 11/11 (queries working correctly!) - test.deno.ts: 11/11 (queries working correctly!)
- test.search.advanced.ts: 41/41 - test.search.advanced.ts: 41/41
@@ -73,6 +83,7 @@ All 157 tests passing across 10 test files:
- And 5 more test files - And 5 more test files
### Migration Learnings for Future Reference: ### Migration Learnings for Future Reference:
1. `context.metadata` is the ONLY way to share state between decorators 1. `context.metadata` is the ONLY way to share state between decorators
2. Class decorators must initialize prototypes from metadata immediately 2. Class decorators must initialize prototypes from metadata immediately
3. `Symbol.metadata` on constructors is read-only (managed by runtime) 3. `Symbol.metadata` on constructors is read-only (managed by runtime)
@@ -82,10 +93,13 @@ All 157 tests passing across 10 test files:
## ES2022 Class Fields & Prototype Getters - Fixed in v7.0.15 ## ES2022 Class Fields & Prototype Getters - Fixed in v7.0.15
### Issue ### Issue
ES2022 class fields (`useDefineForClassFields: true`) create own properties during construction that shadow prototype getters defined by decorators. ES2022 class fields (`useDefineForClassFields: true`) create own properties during construction that shadow prototype getters defined by decorators.
### Solution ### Solution
Use `declare` keyword for instance properties that are accessed via prototype getters: Use `declare` keyword for instance properties that are accessed via prototype getters:
```typescript ```typescript
// In SmartDataDbDoc (ts/classes.doc.ts): // In SmartDataDbDoc (ts/classes.doc.ts):
declare public collection: SmartdataCollection<any>; // Type-only, no JS emitted declare public collection: SmartdataCollection<any>; // Type-only, no JS emitted
@@ -93,6 +107,7 @@ declare public manager: TManager; // Type-only, no JS emitted
``` ```
### Key Insight ### Key Insight
- `declare` tells TypeScript this is a type-only declaration - `declare` tells TypeScript this is a type-only declaration
- No JavaScript code is emitted for `declare` properties - No JavaScript code is emitted for `declare` properties
- Prototype getters defined by `@Collection` and `@managed` decorators are no longer shadowed - Prototype getters defined by `@Collection` and `@managed` decorators are no longer shadowed

216
readme.md
View File

@@ -52,9 +52,9 @@ const db = new SmartdataDb({
mongoDbPass: 'password', mongoDbPass: 'password',
// Optional: Advanced connection pooling // Optional: Advanced connection pooling
maxPoolSize: 100, // Max connections in pool maxPoolSize: 100, // Max connections in pool
maxIdleTimeMS: 300000, // Max idle time before connection close maxIdleTimeMS: 300000, // Max idle time before connection close
serverSelectionTimeoutMS: 30000 // Connection timeout serverSelectionTimeoutMS: 30000, // Connection timeout
}); });
// Initialize with automatic retry and health monitoring // Initialize with automatic retry and health monitoring
@@ -77,25 +77,25 @@ import { ObjectId } from 'mongodb';
@Collection(() => db) @Collection(() => db)
class User extends SmartDataDbDoc<User, User> { class User extends SmartDataDbDoc<User, User> {
@unI() @unI()
public id: string; // Unique index with automatic ID generation public id: string; // Unique index with automatic ID generation
@svDb() @svDb()
@searchable() // Enable Lucene-style searching @searchable() // Enable Lucene-style searching
public username: string; public username: string;
@svDb() @svDb()
@searchable() @searchable()
@index({ unique: false }) // Performance index @index({ unique: false }) // Performance index
public email: string; public email: string;
@svDb() @svDb()
public status: 'active' | 'inactive' | 'pending'; // Full union type support public status: 'active' | 'inactive' | 'pending'; // Full union type support
@svDb() @svDb()
public organizationId: ObjectId; // Native MongoDB types public organizationId: ObjectId; // Native MongoDB types
@svDb() @svDb()
public profilePicture: Buffer; // Binary data support public profilePicture: Buffer; // Binary data support
@svDb({ @svDb({
// Custom serialization for complex objects // Custom serialization for complex objects
@@ -105,7 +105,7 @@ class User extends SmartDataDbDoc<User, User> {
public preferences: Record<string, any>; public preferences: Record<string, any>;
@svDb() @svDb()
public tags: string[]; // Array support with operators public tags: string[]; // Array support with operators
@svDb() @svDb()
public createdAt: Date = new Date(); public createdAt: Date = new Date();
@@ -156,12 +156,12 @@ const john = await User.getInstances({ name: 'John Doe' });
// Multiple fields (implicit AND) // Multiple fields (implicit AND)
const activeAdults = await User.getInstances({ const activeAdults = await User.getInstances({
status: 'active', status: 'active',
age: { $gte: 18 } age: { $gte: 18 },
}); });
// Union types work perfectly // Union types work perfectly
const users = await User.getInstances({ const users = await User.getInstances({
status: { $in: ['active', 'pending'] } // TypeScript validates these values! status: { $in: ['active', 'pending'] }, // TypeScript validates these values!
}); });
``` ```
@@ -173,19 +173,19 @@ SmartData supports **both** nested object notation and dot notation for querying
// Nested object notation - natural TypeScript syntax // Nested object notation - natural TypeScript syntax
const users = await User.getInstances({ const users = await User.getInstances({
metadata: { metadata: {
loginCount: { $gte: 5 } loginCount: { $gte: 5 },
} },
}); });
// Dot notation - MongoDB style // Dot notation - MongoDB style
const sameUsers = await User.getInstances({ const sameUsers = await User.getInstances({
'metadata.loginCount': { $gte: 5 } 'metadata.loginCount': { $gte: 5 },
}); });
// POWERFUL: Combine both notations - operators are merged! // POWERFUL: Combine both notations - operators are merged!
const filtered = await User.getInstances({ const filtered = await User.getInstances({
metadata: { loginCount: { $gte: 3 } }, // Object notation metadata: { loginCount: { $gte: 3 } }, // Object notation
'metadata.loginCount': { $lte: 10 } // Dot notation 'metadata.loginCount': { $lte: 10 }, // Dot notation
// Result: metadata.loginCount between 3 and 10 // Result: metadata.loginCount between 3 and 10
}); });
@@ -195,10 +195,10 @@ const deepQuery = await User.getInstances({
settings: { settings: {
notifications: { notifications: {
email: true, email: true,
frequency: { $in: ['daily', 'weekly'] } frequency: { $in: ['daily', 'weekly'] },
} },
} },
} },
}); });
// Mix styles for complex queries // Mix styles for complex queries
@@ -206,11 +206,11 @@ const advanced = await User.getInstances({
// Object notation for structure // Object notation for structure
profile: { profile: {
age: { $gte: 21 }, age: { $gte: 21 },
verified: true verified: true,
}, },
// Dot notation for specific overrides // Dot notation for specific overrides
'profile.settings.theme': 'dark', 'profile.settings.theme': 'dark',
'profile.lastSeen': { $gte: new Date('2024-01-01') } 'profile.lastSeen': { $gte: new Date('2024-01-01') },
}); });
``` ```
@@ -219,17 +219,17 @@ const advanced = await User.getInstances({
```typescript ```typescript
// Numeric comparisons with type checking // Numeric comparisons with type checking
const adults = await User.getInstances({ const adults = await User.getInstances({
age: { $gte: 18, $lt: 65 } // Type-safe numeric comparisons age: { $gte: 18, $lt: 65 }, // Type-safe numeric comparisons
}); });
// Date comparisons // Date comparisons
const recentUsers = await User.getInstances({ const recentUsers = await User.getInstances({
createdAt: { $gte: new Date('2024-01-01') } createdAt: { $gte: new Date('2024-01-01') },
}); });
// Not equal // Not equal
const nonAdmins = await User.getInstances({ const nonAdmins = await User.getInstances({
role: { $ne: 'admin' } role: { $ne: 'admin' },
}); });
``` ```
@@ -238,23 +238,24 @@ const nonAdmins = await User.getInstances({
```typescript ```typescript
// Array operations with full type safety // Array operations with full type safety
const experts = await User.getInstances({ const experts = await User.getInstances({
tags: { $all: ['typescript', 'mongodb'] }, // Must have all tags tags: { $all: ['typescript', 'mongodb'] }, // Must have all tags
skills: { $size: 5 } // Exactly 5 skills skills: { $size: 5 }, // Exactly 5 skills
}); });
// Array element matching // Array element matching
const results = await Order.getInstances({ const results = await Order.getInstances({
items: { items: {
$elemMatch: { // Match array elements $elemMatch: {
// Match array elements
product: 'laptop', product: 'laptop',
quantity: { $gte: 2 } quantity: { $gte: 2 },
} },
} },
}); });
// Check if value exists in array field // Check if value exists in array field
const nodeUsers = await User.getInstances({ const nodeUsers = await User.getInstances({
skills: { $in: ['nodejs'] } // Has nodejs in skills array skills: { $in: ['nodejs'] }, // Has nodejs in skills array
}); });
``` ```
@@ -266,24 +267,18 @@ const results = await Order.getInstances({
$and: [ $and: [
{ status: { $in: ['pending', 'processing'] } }, { status: { $in: ['pending', 'processing'] } },
{ 'items.price': { $gte: 100 } }, { 'items.price': { $gte: 100 } },
{ customer: { verified: true } } { customer: { verified: true } },
] ],
}); });
// $or operator // $or operator
const urgentOrHighValue = await Order.getInstances({ const urgentOrHighValue = await Order.getInstances({
$or: [ $or: [{ priority: 'urgent' }, { totalAmount: { $gte: 1000 } }],
{ priority: 'urgent' },
{ totalAmount: { $gte: 1000 } }
]
}); });
// $nor operator - none of the conditions // $nor operator - none of the conditions
const excluded = await User.getInstances({ const excluded = await User.getInstances({
$nor: [ $nor: [{ status: 'banned' }, { role: 'guest' }],
{ status: 'banned' },
{ role: 'guest' }
]
}); });
// Combine logical operators // Combine logical operators
@@ -291,12 +286,9 @@ const complex = await Order.getInstances({
$and: [ $and: [
{ status: 'active' }, { status: 'active' },
{ {
$or: [ $or: [{ priority: 'high' }, { value: { $gte: 1000 } }],
{ priority: 'high' }, },
{ value: { $gte: 1000 } } ],
]
}
]
}); });
``` ```
@@ -305,12 +297,12 @@ const complex = await Order.getInstances({
```typescript ```typescript
// Check field existence // Check field existence
const withEmail = await User.getInstances({ const withEmail = await User.getInstances({
email: { $exists: true } email: { $exists: true },
}); });
// Check for null or missing nested fields // Check for null or missing nested fields
const noPreferences = await User.getInstances({ const noPreferences = await User.getInstances({
'profile.preferences': { $exists: false } 'profile.preferences': { $exists: false },
}); });
``` ```
@@ -319,12 +311,12 @@ const noPreferences = await User.getInstances({
```typescript ```typescript
// Regex patterns // Regex patterns
const gmailUsers = await User.getInstances({ const gmailUsers = await User.getInstances({
email: { $regex: '@gmail\\.com$', $options: 'i' } email: { $regex: '@gmail\\.com$', $options: 'i' },
}); });
// Starts with pattern // Starts with pattern
const johnUsers = await User.getInstances({ const johnUsers = await User.getInstances({
name: { $regex: '^John' } name: { $regex: '^John' },
}); });
``` ```
@@ -349,22 +341,21 @@ const advancedQuery = await User.getInstances({
// Nested object with operators // Nested object with operators
profile: { profile: {
age: { $gte: 18, $lte: 65 }, age: { $gte: 18, $lte: 65 },
verified: true verified: true,
}, },
// Dot notation for deep paths // Dot notation for deep paths
'settings.notifications.email': true, 'settings.notifications.email': true,
'metadata.lastLogin': { $gte: new Date(Date.now() - 30*24*60*60*1000) }, 'metadata.lastLogin': {
$gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
},
// Array operations // Array operations
roles: { $in: ['admin', 'moderator'] }, roles: { $in: ['admin', 'moderator'] },
tags: { $all: ['verified', 'premium'] }, tags: { $all: ['verified', 'premium'] },
// Logical grouping // Logical grouping
$or: [ $or: [{ 'subscription.plan': 'premium' }, { 'subscription.trial': true }],
{ 'subscription.plan': 'premium' },
{ 'subscription.trial': true }
]
}); });
``` ```
@@ -400,7 +391,7 @@ const exact = await Product.search('"MacBook Pro 16"');
// Combined with filters for powerful queries // Combined with filters for powerful queries
const affordable = await Product.search('laptop', { const affordable = await Product.search('laptop', {
filter: { price: { $lte: 1500 } }, filter: { price: { $lte: 1500 } },
validate: async (p) => p.inStock === true validate: async (p) => p.inStock === true,
}); });
``` ```
@@ -427,7 +418,7 @@ const config = await db.createEasyStore<AppConfig>('app-config');
// Write with full type checking // Write with full type checking
await config.writeKey('features', { await config.writeKey('features', {
darkMode: true, darkMode: true,
notifications: false notifications: false,
}); });
// Read with guaranteed types // Read with guaranteed types
@@ -437,7 +428,7 @@ const features = await config.readKey('features');
// Atomic updates // Atomic updates
await config.updateKey('limits', (current) => ({ await config.updateKey('limits', (current) => ({
...current, ...current,
maxUsers: current.maxUsers + 100 maxUsers: current.maxUsers + 100,
})); }));
// Delete keys // Delete keys
@@ -454,11 +445,11 @@ React to database changes instantly with RxJS integration:
```typescript ```typescript
// Watch for changes with automatic reconnection // Watch for changes with automatic reconnection
const watcher = await User.watch( const watcher = await User.watch(
{ status: 'active' }, // Filter which documents to watch { status: 'active' }, // Filter which documents to watch
{ {
fullDocument: 'updateLookup', // Get full document on updates fullDocument: 'updateLookup', // Get full document on updates
bufferTimeMs: 100 // Buffer changes for efficiency bufferTimeMs: 100, // Buffer changes for efficiency
} },
); );
// Subscribe to changes with RxJS // Subscribe to changes with RxJS
@@ -466,7 +457,7 @@ watcher.changeSubject.subscribe({
next: (change) => { next: (change) => {
console.log('User changed:', change.fullDocument); console.log('User changed:', change.fullDocument);
switch(change.operationType) { switch (change.operationType) {
case 'insert': case 'insert':
console.log('New user created'); console.log('New user created');
break; break;
@@ -478,7 +469,7 @@ watcher.changeSubject.subscribe({
break; break;
} }
}, },
error: (err) => console.error('Watch error:', err) error: (err) => console.error('Watch error:', err),
}); });
// Advanced: Watch with aggregation pipeline // Advanced: Watch with aggregation pipeline
@@ -487,9 +478,9 @@ const complexWatcher = await Order.watch(
{ {
pipeline: [ pipeline: [
{ $match: { 'fullDocument.totalAmount': { $gte: 1000 } } }, { $match: { 'fullDocument.totalAmount': { $gte: 1000 } } },
{ $addFields: { isHighValue: true } } { $addFields: { isHighValue: true } },
] ],
} },
); );
// Clean up when done // Clean up when done
@@ -522,7 +513,7 @@ const isLeader = coordinator.isLeader;
const result = await coordinator.fireDistributedTaskRequest({ const result = await coordinator.fireDistributedTaskRequest({
taskName: 'process-payments', taskName: 'process-payments',
taskExecutionTime: Date.now(), taskExecutionTime: Date.now(),
requestResponseId: 'unique-id' requestResponseId: 'unique-id',
}); });
// Graceful shutdown with leadership handoff // Graceful shutdown with leadership handoff
@@ -539,11 +530,12 @@ const cursor = await User.getCursor(
{ status: 'active' }, { status: 'active' },
{ {
// Optional: Use MongoDB native cursor modifiers // Optional: Use MongoDB native cursor modifiers
modifier: (cursor) => cursor modifier: (cursor) =>
.sort({ createdAt: -1 }) cursor
.limit(10000) .sort({ createdAt: -1 })
.project({ email: 1, username: 1 }) .limit(10000)
} .project({ email: 1, username: 1 }),
},
); );
// Process one at a time // Process one at a time
@@ -574,16 +566,13 @@ try {
// All operations in this block are atomic // All operations in this block are atomic
const sender = await User.getInstance( const sender = await User.getInstance(
{ id: 'user-1' }, { id: 'user-1' },
{ session } // Pass session to all operations { session }, // Pass session to all operations
); );
sender.balance -= 100; sender.balance -= 100;
await sender.save({ session }); await sender.save({ session });
const receiver = await User.getInstance( const receiver = await User.getInstance({ id: 'user-2' }, { session });
{ id: 'user-2' },
{ session }
);
receiver.balance += 100; receiver.balance += 100;
await receiver.save({ session }); await receiver.save({ session });
@@ -609,28 +598,28 @@ class Document extends SmartDataDbDoc<Document, Document> {
@svDb({ @svDb({
// Encrypt sensitive data before storing // Encrypt sensitive data before storing
serialize: async (value) => await encrypt(value), serialize: async (value) => await encrypt(value),
deserialize: async (value) => await decrypt(value) deserialize: async (value) => await decrypt(value),
}) })
public sensitiveData: string; public sensitiveData: string;
@svDb({ @svDb({
// Compress large JSON objects // Compress large JSON objects
serialize: (value) => compress(JSON.stringify(value)), serialize: (value) => compress(JSON.stringify(value)),
deserialize: (value) => JSON.parse(decompress(value)) deserialize: (value) => JSON.parse(decompress(value)),
}) })
public largePayload: any; public largePayload: any;
@svDb({ @svDb({
// Store Sets as arrays // Store Sets as arrays
serialize: (set) => Array.from(set), serialize: (set) => Array.from(set),
deserialize: (arr) => new Set(arr) deserialize: (arr) => new Set(arr),
}) })
public tags: Set<string>; public tags: Set<string>;
@svDb({ @svDb({
// Handle custom date formats // Handle custom date formats
serialize: (date) => date?.toISOString(), serialize: (date) => date?.toISOString(),
deserialize: (str) => str ? new Date(str) : null deserialize: (str) => (str ? new Date(str) : null),
}) })
public scheduledAt: Date | null; public scheduledAt: Date | null;
} }
@@ -651,8 +640,9 @@ class Order extends SmartDataDbDoc<Order, Order> {
// Called before saving (create or update) // Called before saving (create or update)
async beforeSave() { async beforeSave() {
// Recalculate total // Recalculate total
this.totalAmount = this.items.reduce((sum, item) => this.totalAmount = this.items.reduce(
sum + (item.price * item.quantity), 0 (sum, item) => sum + item.price * item.quantity,
0,
); );
// Validate // Validate
@@ -698,34 +688,37 @@ class Order extends SmartDataDbDoc<Order, Order> {
```typescript ```typescript
@Collection(() => db) @Collection(() => db)
class HighPerformanceDoc extends SmartDataDbDoc<HighPerformanceDoc, HighPerformanceDoc> { class HighPerformanceDoc extends SmartDataDbDoc<
@unI() // Unique index HighPerformanceDoc,
HighPerformanceDoc
> {
@unI() // Unique index
public id: string; public id: string;
@index() // Single field index @index() // Single field index
public userId: string; public userId: string;
@index({ sparse: true }) // Sparse index for optional fields @index({ sparse: true }) // Sparse index for optional fields
public deletedAt?: Date; public deletedAt?: Date;
@index({ @index({
unique: false, unique: false,
background: true, // Non-blocking index creation background: true, // Non-blocking index creation
expireAfterSeconds: 86400 // TTL index expireAfterSeconds: 86400, // TTL index
}) })
public sessionToken: string; public sessionToken: string;
// Compound indexes for complex queries // Compound indexes for complex queries
static async createIndexes() { static async createIndexes() {
await this.collection.createIndex( await this.collection.createIndex(
{ userId: 1, createdAt: -1 }, // Compound index { userId: 1, createdAt: -1 }, // Compound index
{ name: 'user_activity_idx' } { name: 'user_activity_idx' },
); );
// Text index for search // Text index for search
await this.collection.createIndex( await this.collection.createIndex(
{ title: 'text', content: 'text' }, { title: 'text', content: 'text' },
{ weights: { title: 10, content: 5 } } { weights: { title: 10, content: 5 } },
); );
} }
} }
@@ -739,18 +732,18 @@ const db = new SmartdataDb({
mongoDbName: 'myapp', mongoDbName: 'myapp',
// Connection pool optimization // Connection pool optimization
maxPoolSize: 100, // Maximum connections maxPoolSize: 100, // Maximum connections
minPoolSize: 10, // Minimum connections to maintain minPoolSize: 10, // Minimum connections to maintain
maxIdleTimeMS: 300000, // Close idle connections after 5 minutes maxIdleTimeMS: 300000, // Close idle connections after 5 minutes
waitQueueTimeoutMS: 5000, // Max time to wait for available connection waitQueueTimeoutMS: 5000, // Max time to wait for available connection
// Server selection // Server selection
serverSelectionTimeoutMS: 30000, // Timeout for selecting a server serverSelectionTimeoutMS: 30000, // Timeout for selecting a server
heartbeatFrequencyMS: 10000, // How often to check server status heartbeatFrequencyMS: 10000, // How often to check server status
// Socket settings // Socket settings
socketTimeoutMS: 360000, // Socket timeout (6 minutes) socketTimeoutMS: 360000, // Socket timeout (6 minutes)
family: 4, // Force IPv4 family: 4, // Force IPv4
}); });
``` ```
@@ -759,6 +752,7 @@ const db = new SmartdataDb({
### 1. Always Use TypeScript ### 1. Always Use TypeScript
SmartData is built for TypeScript. Using JavaScript means missing out on: SmartData is built for TypeScript. Using JavaScript means missing out on:
- Compile-time query validation - Compile-time query validation
- IntelliSense for MongoDB operators - IntelliSense for MongoDB operators
- Type-safe document updates - Type-safe document updates
@@ -785,7 +779,7 @@ await session.withTransaction(async () => {
}); });
// ❌ Bad: Multiple operations without transactions // ❌ Bad: Multiple operations without transactions
await debitAccount(fromAccount, amount); // What if this fails? await debitAccount(fromAccount, amount); // What if this fails?
await creditAccount(toAccount, amount); await creditAccount(toAccount, amount);
``` ```
@@ -799,7 +793,7 @@ await cursor.forEach(async (doc) => {
}); });
// ❌ Bad: Loading everything into memory // ❌ Bad: Loading everything into memory
const allDocs = await LargeCollection.getInstances({}); // Could OOM! const allDocs = await LargeCollection.getInstances({}); // Could OOM!
``` ```
### 5. Implement Proper Error Handling ### 5. Implement Proper Error Handling
@@ -819,7 +813,7 @@ try {
// ❌ Bad: Ignoring errors // ❌ Bad: Ignoring errors
const user = await User.getInstance({ id: userId }); const user = await User.getInstance({ id: userId });
await processUser(user); // What if user is null? await processUser(user); // What if user is null?
``` ```
## 🔧 Troubleshooting ## 🔧 Troubleshooting
@@ -854,17 +848,17 @@ Always clean up resources:
// Watchers // Watchers
const watcher = await User.watch({}); const watcher = await User.watch({});
// ... use watcher // ... use watcher
await watcher.close(); // Always close! await watcher.close(); // Always close!
// Cursors // Cursors
const cursor = await User.getCursor({}); const cursor = await User.getCursor({});
// ... use cursor // ... use cursor
await cursor.close(); // Always close! await cursor.close(); // Always close!
// Sessions // Sessions
const session = db.startSession(); const session = db.startSession();
// ... use session // ... use session
await session.endSession(); // Always end! await session.endSession(); // Always end!
``` ```
### Performance Issues ### Performance Issues

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 smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js'; import { smartunique } from '../ts/plugins.js';
import * as smartdata from '../ts/index.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 // 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 { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo'; import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js'; 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 smartmongo from '@push.rocks/smartmongo';
import type * as taskbuffer from '@push.rocks/taskbuffer'; 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 { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo'; import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js'; 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 // 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 { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo'; import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js'; 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 smartmongo from '@push.rocks/smartmongo';
import * as smartdata from '../ts/index.js'; import * as smartdata from '../ts/index.js';
import { searchable } from '../ts/classes.doc.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 * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js'; 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 { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo'; import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js'; 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 { Qenv } from '@push.rocks/qenv';
import * as smartmongo from '@push.rocks/smartmongo'; import * as smartmongo from '@push.rocks/smartmongo';
import { smartunique } from '../ts/plugins.js'; import { smartunique } from '../ts/plugins.js';

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartdata', name: '@push.rocks/smartdata',
version: '7.1.0', version: '7.1.1',
description: 'An advanced library for NoSQL data organization and manipulation using TypeScript with support for MongoDB, data validation, collections, and custom data types.' 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

@@ -174,8 +174,8 @@ export class SmartdataCollection<T> {
/** /**
* the collection that is used * the collection that is used
*/ */
public mongoDbCollection: plugins.mongodb.Collection; public mongoDbCollection!: plugins.mongodb.Collection;
public objectValidation: IDocValidationFunc<T> = null; public objectValidation: IDocValidationFunc<T> | null = null;
public collectionName: string; public collectionName: string;
public smartdataDb: SmartdataDb; public smartdataDb: SmartdataDb;
public uniqueIndexes: string[] = []; public uniqueIndexes: string[] = [];
@@ -330,7 +330,7 @@ export class SmartdataCollection<T> {
); );
const smartdataWatcher = new SmartdataDbWatcher( const smartdataWatcher = new SmartdataDbWatcher(
changeStream, changeStream,
smartdataDbDocArg, smartdataDbDocArg!,
{ bufferTimeMs }, { bufferTimeMs },
); );
await smartdataWatcher.readyDeferred.promise; await smartdataWatcher.readyDeferred.promise;
@@ -353,7 +353,7 @@ export class SmartdataCollection<T> {
this.createRegularIndexes(dbDocArg.regularIndexes); 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 }); const result = await this.mongoDbCollection.insertOne(saveableObject, { session: opts?.session });
return result; return result;
} }
@@ -368,7 +368,7 @@ export class SmartdataCollection<T> {
await this.init(); await this.init();
await this.checkDoc(dbDocArg); await this.checkDoc(dbDocArg);
const identifiableObject = await dbDocArg.createIdentifiableObject(); const identifiableObject = await dbDocArg.createIdentifiableObject();
const saveableObject = await dbDocArg.createSavableObject(); const saveableObject = await dbDocArg.createSavableObject() as any;
const updateableObject: any = {}; const updateableObject: any = {};
for (const key of Object.keys(saveableObject)) { for (const key of Object.keys(saveableObject)) {
if (identifiableObject[key]) { if (identifiableObject[key]) {

View File

@@ -12,8 +12,8 @@ export type TConnectionStatus = 'initial' | 'disconnected' | 'connected' | 'fail
export class SmartdataDb { export class SmartdataDb {
smartdataOptions: plugins.tsclass.database.IMongoDescriptor; smartdataOptions: plugins.tsclass.database.IMongoDescriptor;
mongoDbClient: plugins.mongodb.MongoClient; mongoDbClient!: plugins.mongodb.MongoClient;
mongoDb: plugins.mongodb.Db; mongoDb!: plugins.mongodb.Db;
status: TConnectionStatus; status: TConnectionStatus;
statusConnectedDeferred = plugins.smartpromise.defer(); statusConnectedDeferred = plugins.smartpromise.defer();
smartdataCollectionMap = new plugins.lik.ObjectMap<SmartdataCollection<any>>(); smartdataCollectionMap = new plugins.lik.ObjectMap<SmartdataCollection<any>>();
@@ -51,8 +51,8 @@ export class SmartdataDb {
.replace('<user>', encodedUser) .replace('<user>', encodedUser)
.replace('<PASSWORD>', encodedPass) .replace('<PASSWORD>', encodedPass)
.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 = { const clientOptions: plugins.mongodb.MongoClientOptions = {
maxPoolSize: (this.smartdataOptions as any).maxPoolSize ?? 100, maxPoolSize: (this.smartdataOptions as any).maxPoolSize ?? 100,
@@ -70,7 +70,7 @@ export class SmartdataDb {
} catch (error) { } catch (error) {
this.status = 'disconnected'; this.status = 'disconnected';
this.statusConnectedDeferred.reject(error); 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; throw error;
} }
} }

View File

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

View File

@@ -482,7 +482,7 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
convertFilterForMongoDb(filterArg), convertFilterForMongoDb(filterArg),
{ session: opts?.session }, { session: opts?.session },
); );
const returnArray = []; const returnArray: T[] = [];
for (const foundDoc of foundDocs) { for (const foundDoc of foundDocs) {
const newInstance: T = (this as any).createInstanceFromMongoDbNativeDoc(foundDoc); const newInstance: T = (this as any).createInstanceFromMongoDbNativeDoc(foundDoc);
returnArray.push(newInstance); returnArray.push(newInstance);
@@ -510,7 +510,7 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
const newInstance: T = (this as any).createInstanceFromMongoDbNativeDoc(foundDoc); const newInstance: T = (this as any).createInstanceFromMongoDbNativeDoc(foundDoc);
return newInstance; return newInstance;
} else { } else {
return null; return null as any;
} }
} }
@@ -833,12 +833,12 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
/** /**
* name * name
*/ */
public name: string; public name!: string;
/** /**
* primary id in the database * primary id in the database
*/ */
public dbDocUniqueId: string; public dbDocUniqueId!: string;
/** /**
* class constructor * class constructor
@@ -898,7 +898,7 @@ export class SmartDataDbDoc<T extends TImplements, TImplements, TManager extends
* also store any referenced objects to DB * also store any referenced objects to DB
* better for data consistency * 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) { if (!savedMapArg) {
savedMapArg = new plugins.lik.ObjectMap<SmartDataDbDoc<any, any>>(); savedMapArg = new plugins.lik.ObjectMap<SmartDataDbDoc<any, any>>();
} }

View File

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

View File

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

View File

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

View File

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