fix(build): update build and test tooling configuration, migrate project config to .smartconfig.json, and align TypeScript typings
This commit is contained in:
@@ -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}}
|
||||||
|
|||||||
@@ -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
8
.gitignore
vendored
@@ -16,4 +16,12 @@ node_modules/
|
|||||||
dist/
|
dist/
|
||||||
dist_*/
|
dist_*/
|
||||||
|
|
||||||
|
# rust
|
||||||
|
rust/target/
|
||||||
|
dist_rust/
|
||||||
|
|
||||||
|
# AI
|
||||||
|
.claude/
|
||||||
|
.serena/
|
||||||
|
|
||||||
#------# custom
|
#------# custom
|
||||||
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@@ -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
|
|
||||||
}
|
}
|
||||||
|
|||||||
111
changelog.md
111
changelog.md
@@ -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 Lucene‑style search examples and use cases
|
- Updated readme.md with detailed Lucene‑style 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
|
||||||
|
|
||||||
|
|||||||
31
package.json
31
package.json
@@ -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
3384
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
|||||||
onlyBuiltDependencies:
|
|
||||||
- esbuild
|
|
||||||
- mongodb-memory-server
|
|
||||||
- puppeteer
|
|
||||||
@@ -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
216
readme.md
@@ -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
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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';
|
||||||
|
|||||||
@@ -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.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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]) {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>>();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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') {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user