proto.io 0.0.223 → 0.0.225

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/dist/adapters/file/aliyun-oss.d.ts +3 -3
  2. package/dist/adapters/file/aliyun-oss.d.ts.map +1 -1
  3. package/dist/adapters/file/aliyun-oss.js.map +1 -1
  4. package/dist/adapters/file/aliyun-oss.mjs.map +1 -1
  5. package/dist/adapters/file/database.d.ts +2 -2
  6. package/dist/adapters/file/database.d.ts.map +1 -1
  7. package/dist/adapters/file/database.js +1 -1
  8. package/dist/adapters/file/database.js.map +1 -1
  9. package/dist/adapters/file/database.mjs +2 -2
  10. package/dist/adapters/file/database.mjs.map +1 -1
  11. package/dist/adapters/file/filesystem.d.ts +3 -3
  12. package/dist/adapters/file/filesystem.d.ts.map +1 -1
  13. package/dist/adapters/file/filesystem.js.map +1 -1
  14. package/dist/adapters/file/filesystem.mjs.map +1 -1
  15. package/dist/adapters/file/google-cloud-storage.d.ts +3 -3
  16. package/dist/adapters/file/google-cloud-storage.d.ts.map +1 -1
  17. package/dist/adapters/file/google-cloud-storage.js.map +1 -1
  18. package/dist/adapters/file/google-cloud-storage.mjs.map +1 -1
  19. package/dist/adapters/storage/progres.d.ts +1 -1
  20. package/dist/adapters/storage/progres.d.ts.map +1 -1
  21. package/dist/adapters/storage/progres.js +4 -4
  22. package/dist/adapters/storage/progres.js.map +1 -1
  23. package/dist/adapters/storage/progres.mjs +7 -7
  24. package/dist/adapters/storage/progres.mjs.map +1 -1
  25. package/dist/client.d.ts +3 -3
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +1 -1
  28. package/dist/client.mjs +4 -4
  29. package/dist/index.d.ts +3 -3
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +54 -51
  32. package/dist/index.js.map +1 -1
  33. package/dist/index.mjs +57 -54
  34. package/dist/index.mjs.map +1 -1
  35. package/dist/internals/{base-D7eiLTdl.d.ts → base-DPYj2_4S.d.ts} +4 -3
  36. package/dist/internals/base-DPYj2_4S.d.ts.map +1 -0
  37. package/dist/internals/base-DYc1_peK.mjs.map +1 -1
  38. package/dist/internals/base-NsJYo2MG.js.map +1 -1
  39. package/dist/internals/{chunk-B95QS-B7.d.ts → chunk-B9XHpR52.d.ts} +3 -3
  40. package/dist/internals/chunk-B9XHpR52.d.ts.map +1 -0
  41. package/dist/internals/chunk-BuKmyceG.js.map +1 -1
  42. package/dist/internals/chunk-bpt1C6W4.mjs.map +1 -1
  43. package/dist/internals/{const-DqPhhmor.mjs → const-68KwNmag.mjs} +2 -2
  44. package/dist/internals/{const-DqPhhmor.mjs.map → const-68KwNmag.mjs.map} +1 -1
  45. package/dist/internals/{index-BozJOOCD.mjs → index-BWZIV3_T.mjs} +15 -4
  46. package/dist/internals/index-BWZIV3_T.mjs.map +1 -0
  47. package/dist/internals/{index-B9kyejqo.d.ts → index-Bi9H_aYC.d.ts} +86 -36
  48. package/dist/internals/index-Bi9H_aYC.d.ts.map +1 -0
  49. package/dist/internals/index-CLKTEIj0.js.map +1 -1
  50. package/dist/internals/{index-gWcE22mf.mjs → index-CSOoWRr1.mjs} +2 -2
  51. package/dist/internals/index-CSOoWRr1.mjs.map +1 -0
  52. package/dist/internals/{index-C01HL8O6.js → index-vOFh8pVc.js} +12 -1
  53. package/dist/internals/index-vOFh8pVc.js.map +1 -0
  54. package/dist/internals/{index-DRgs8WkW.d.ts → index-y_bUWp3C.d.ts} +3 -2
  55. package/dist/internals/index-y_bUWp3C.d.ts.map +1 -0
  56. package/dist/internals/random-CYjWDvex.mjs.map +1 -1
  57. package/dist/internals/random-nkOQ9U6S.js.map +1 -1
  58. package/dist/internals/{validator-B5yHpyvb.js → validator-Bc1jRJfA.js} +42 -10
  59. package/dist/internals/validator-Bc1jRJfA.js.map +1 -0
  60. package/dist/internals/{validator-DX2nXeQo.mjs → validator-Boj1PUjM.mjs} +43 -11
  61. package/dist/internals/validator-Boj1PUjM.mjs.map +1 -0
  62. package/package.json +23 -23
  63. package/dist/internals/base-D7eiLTdl.d.ts.map +0 -1
  64. package/dist/internals/chunk-B95QS-B7.d.ts.map +0 -1
  65. package/dist/internals/index-B9kyejqo.d.ts.map +0 -1
  66. package/dist/internals/index-BozJOOCD.mjs.map +0 -1
  67. package/dist/internals/index-C01HL8O6.js.map +0 -1
  68. package/dist/internals/index-DRgs8WkW.d.ts.map +0 -1
  69. package/dist/internals/index-gWcE22mf.mjs.map +0 -1
  70. package/dist/internals/validator-B5yHpyvb.js.map +0 -1
  71. package/dist/internals/validator-DX2nXeQo.mjs.map +0 -1
package/dist/client.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { P as ProtoClient } from './internals/index-DRgs8WkW.js';
2
- export { c as classExtends } from './internals/index-DRgs8WkW.js';
3
- export { D as DeserializeOptions, S as SerializeOptions, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-B9kyejqo.js';
1
+ import { P as ProtoClient } from './internals/index-y_bUWp3C.js';
2
+ export { c as classExtends } from './internals/index-y_bUWp3C.js';
3
+ export { D as DeserializeOptions, S as SerializeOptions, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-Bi9H_aYC.js';
4
4
  export { Decimal } from 'decimal.js';
5
5
  import '@o2ter/utils-js';
6
6
  import 'socket.io-client';
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"client.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;"}
package/dist/client.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var index = require('./internals/index-C01HL8O6.js');
5
+ var index = require('./internals/index-vOFh8pVc.js');
6
6
  var Decimal = require('decimal.js');
7
7
  require('@o2ter/utils-js');
8
8
  require('./internals/private-Ciddhure.js');
package/dist/client.mjs CHANGED
@@ -1,12 +1,12 @@
1
- import { b as ProtoClient } from './internals/index-BozJOOCD.mjs';
2
- export { c as classExtends, d as deserialize, s as serialize } from './internals/index-BozJOOCD.mjs';
1
+ import { b as ProtoClient } from './internals/index-BWZIV3_T.mjs';
2
+ export { c as classExtends, d as deserialize, s as serialize } from './internals/index-BWZIV3_T.mjs';
3
3
  export { Decimal } from 'decimal.js';
4
4
  import '@o2ter/utils-js';
5
5
  import './internals/private-CNw40LZ7.mjs';
6
6
  import 'lodash';
7
- import './internals/index-gWcE22mf.mjs';
7
+ import './internals/index-CSOoWRr1.mjs';
8
8
  import 'axios';
9
- import './internals/const-DqPhhmor.mjs';
9
+ import './internals/const-68KwNmag.mjs';
10
10
  import '@o2ter/server-js/dist/const';
11
11
  import 'socket.io-client';
12
12
  import '@o2ter/crypto-js';
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  import * as socket_io from 'socket.io';
2
2
  import { Router } from 'express';
3
3
  import { Server } from '@o2ter/server-js';
4
- import { T as TSchema, a as TValueWithoutObject, P as ProtoService, b as ProtoServiceOptions, c as ProtoServiceKeyOptions } from './internals/index-B9kyejqo.js';
5
- export { D as DeserializeOptions, S as SerializeOptions, d as TFileStorage, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-B9kyejqo.js';
4
+ import { P as ProtoService, a as ProtoServiceOptions, b as ProtoServiceKeyOptions, T as TSchema, c as TValueWithoutObject } from './internals/index-Bi9H_aYC.js';
5
+ export { D as DeserializeOptions, S as SerializeOptions, d as TFileStorage, e as TNumber, f as TSerializable, g as deserialize, s as serialize } from './internals/index-Bi9H_aYC.js';
6
6
  import Decimal from 'decimal.js';
7
7
  export { Decimal } from 'decimal.js';
8
- export { P as ProtoClient, c as classExtends } from './internals/index-DRgs8WkW.js';
8
+ export { P as ProtoClient, c as classExtends } from './internals/index-y_bUWp3C.js';
9
9
  import '@o2ter/utils-js';
10
10
  import 'jsonwebtoken';
11
11
  import 'lodash';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sources":[],"sourcesContent":[],"names":[],"mappings":""}
1
+ {"version":3,"file":"index.d.ts","sources":["../src/index.ts"],"sourcesContent":["//\n// index.ts\n//\n// The MIT License\n// Copyright (c) 2021 - 2025 O2ter Limited. All rights reserved.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a copy\n// of this software and associated documentation files (the \"Software\"), to deal\n// in the Software without restriction, including without limitation the rights\n// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n// copies of the Software, and to permit persons to whom the Software is\n// furnished to do so, subject to the following conditions:\n//\n// The above copyright notice and this permission notice shall be included in\n// all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n// THE SOFTWARE.\n//\n\nimport _ from 'lodash';\nimport { Router } from 'express';\nimport { Server } from '@o2ter/server-js';\nimport { ProtoService } from './server/proto';\nimport { ProtoServiceKeyOptions, ProtoServiceOptions } from './server/proto/types';\nimport authHandler from './server/auth';\nimport classesRoute from './server/routes/classes';\nimport functionRoute from './server/routes/function';\nimport jobRoute from './server/routes/job';\nimport filesRoute from './server/routes/files';\nimport userRoute from './server/routes/user';\nimport notifyRoute from './server/routes/notify';\nimport schemaRoute from './server/routes/schema';\nimport configRoute from './server/routes/config';\nimport { TSchema } from './internals/schema';\nimport { PVK } from './internals/private';\nimport { TValueWithoutObject } from './internals/types';\nimport Decimal from 'decimal.js';\nimport { response } from './server/routes/common';\nimport { QuerySelector } from './server/query/dispatcher/parser';\nimport { serialize } from './internals/codec';\n\nexport * from './internals/codec';\nexport { classExtends } from './internals/utils';\nexport { TFileStorage } from './server/file';\nexport { ProtoService } from './server/proto';\nexport { ProtoClient } from './client';\n\n/**\n * Schema definition utility functions.\n */\nexport const schema = _.assign((x: Record<string, TSchema>) => x, {\n /**\n * Defines a boolean schema.\n * @param defaultValue - The default value for the boolean.\n * @returns The boolean schema.\n */\n boolean: (defaultValue?: boolean) => ({ type: 'boolean', default: defaultValue }) as const,\n\n /**\n * Defines a number schema.\n * @param defaultValue - The default value for the number.\n * @returns The number schema.\n */\n number: (defaultValue?: number) => ({ type: 'number', default: defaultValue }) as const,\n\n /**\n * Defines a decimal schema.\n * @param defaultValue - The default value for the decimal.\n * @returns The decimal schema.\n */\n decimal: (defaultValue?: Decimal) => ({ type: 'decimal', default: defaultValue }) as const,\n\n /**\n * Defines a string schema.\n * @param defaultValue - The default value for the string.\n * @returns The string schema.\n */\n string: (defaultValue?: string) => ({ type: 'string', default: defaultValue }) as const,\n\n /**\n * Defines a string array schema.\n * @param defaultValue - The default value for the string array.\n * @returns The string array schema.\n */\n stringArray: (defaultValue?: string[]) => ({ type: 'string[]', default: defaultValue }) as const,\n\n /**\n * Defines a date schema.\n * @param defaultValue - The default value for the date.\n * @returns The date schema.\n */\n date: (defaultValue?: Date) => ({ type: 'date', default: defaultValue }) as const,\n\n /**\n * Defines an object schema.\n * @param defaultValue - The default value for the object.\n * @returns The object schema.\n */\n object: <T extends Record<string, TValueWithoutObject>>(defaultValue?: T) => ({ type: 'object', default: defaultValue }) as const,\n\n /**\n * Defines an array schema.\n * @param defaultValue - The default value for the array.\n * @returns The array schema.\n */\n array: <T extends TValueWithoutObject[]>(defaultValue?: T) => ({ type: 'array', default: defaultValue }) as const,\n\n /**\n * Defines a vector schema.\n * @param dimension - The dimension of the vector.\n * @param defaultValue - The default value for the vector.\n * @returns The vector schema.\n */\n vector: (dimension: number, defaultValue?: number[]) => ({ type: 'vector', dimension, default: defaultValue }) as const,\n\n /**\n * Defines a shape schema.\n * @param shape - The shape definition.\n * @returns The shape schema.\n */\n shape: (shape: Record<string, TSchema.DataType>) => ({ type: 'shape', shape }) as const,\n\n /**\n * Defines a pointer schema.\n * @param target - The target of the pointer.\n * @returns The pointer schema.\n */\n pointer: (target: string) => ({ type: 'pointer', target }) as const,\n\n /**\n * Defines a relation schema.\n * @param target - The target of the relation.\n * @param foreignField - The foreign field of the relation.\n * @returns The relation schema.\n */\n relation: (target: string, foreignField?: string) => ({ type: 'relation', target, foreignField }) as const,\n});\n\n/**\n * Creates a ProtoRoute.\n * @param options - The options for the ProtoRoute.\n * @returns A promise that resolves to a Router.\n */\nexport const ProtoRoute = async <E>(options: {\n proto: ProtoService<E> | (ProtoServiceOptions<E> & ProtoServiceKeyOptions);\n}): Promise<Router> => {\n\n const proto = options.proto instanceof ProtoService ? options.proto : new ProtoService(options.proto);\n await proto[PVK].prepare();\n\n const router = Server.Router().use(\n authHandler(proto),\n (req, res, next) => {\n const payload = proto.connect(req);\n if (!payload.isInvalidMasterToken) return next();\n res.status(400).json({ message: 'Invalid token' });\n },\n );\n\n router.get('/health', (req, res) => { res.sendStatus(200); });\n router.get('/sessionInfo', async (req, res) => {\n await response(res, () => proto.connect(req).sessionInfo());\n });\n\n classesRoute(router, proto);\n functionRoute(router, proto);\n jobRoute(router, proto);\n filesRoute(router, proto);\n userRoute(router, proto);\n notifyRoute(router, proto);\n schemaRoute(router, proto);\n configRoute(router, proto);\n\n return router;\n}\n\n/**\n * Registers a ProtoSocket.\n * @param proto - The ProtoService instance.\n * @param server - The server instance.\n * @param endpoint - The optional endpoint.\n * @returns The socket.io instance.\n */\nexport const registerProtoSocket = <E>(\n proto: ProtoService<E>,\n server: Server,\n endpoint?: string,\n) => {\n const io = endpoint ? server.socket().of(endpoint) : server.socket();\n\n io.on('connection', async (socket) => {\n\n let { token } = socket.handshake.auth;\n const service = await proto.connectWithSessionToken(token);\n\n socket.on('auth', (t) => {\n token = t;\n service.connectWithSessionToken(t);\n });\n\n type QueryOpts = {\n event: string;\n className: string;\n filter: QuerySelector | boolean;\n };\n\n let events: Record<string, QuerySelector | boolean> = {};\n let queries: Record<string, QueryOpts> = {};\n\n const { remove: remove_basic } = service.listen(data => {\n const ids = _.keys(_.pickBy(events, v => v instanceof QuerySelector ? v.eval(data) : v));\n const payload = JSON.parse(serialize(data));\n if (!_.isEmpty(ids)) socket.emit('ON_EV_NOTIFY', { ids, data: payload });\n });\n\n const { remove: remove_livequery } = service[PVK]._liveQuery(service, (ev, objs) => {\n const ids: Record<string, string[]> = {};\n for (const obj of objs) {\n ids[obj.id!] = _.keys(_.pickBy(queries, v => {\n if (v.event !== ev || v.className !== obj.className) return false;\n return v.filter instanceof QuerySelector ? v.filter.eval(obj) : v.filter;\n }));\n }\n if (_.isEmpty(ids)) return;\n const payload = JSON.parse(serialize(_.filter(objs, obj => !_.isEmpty(ids[obj.id!]))));\n socket.emit('ON_EV_LIVEQUERY', { ids, data: payload });\n });\n\n socket.on('disconnect', () => {\n remove_basic();\n remove_livequery();\n });\n\n socket.on('EV_NOTIFY', (payload) => {\n events = _.mapValues(payload, v => {\n if (_.isBoolean(v)) return true;\n try {\n return QuerySelector.decode(v);\n } catch (error) {\n proto.logger.error(error);\n return false;\n }\n });\n });\n\n socket.on('EV_LIVEQUERY', (payload) => {\n queries = _.mapValues(payload, v => {\n const { event = '', className = '', filter } = v ?? {};\n if (_.isBoolean(v)) return { event, className, filter: true };\n try {\n return { event, className, filter: QuerySelector.decode(filter) };\n } catch (error) {\n proto.logger.error(error);\n return { event, className, filter: false };\n }\n });\n });\n });\n\n return io;\n}\n\nexport default ProtoRoute;"],"names":[],"mappings":";;;;;;;;;;;;;;;AAYA;AACA;AACA;AACO,cAAA,MAAA,OAAA,MAAA,SAAA,OAAA,MAAA,MAAA,SAAA,OAAA;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAAA,OAAA;AACA;AACA,0BAAA,OAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAAA,IAAA;AACA;AACA,0BAAA,IAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAA,MAAA,SAAA,mBAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAA,mBAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAA,MAAA,SAAA,OAAA,CAAA,QAAA;AACA;AACA,wBAAA,MAAA,SAAA,OAAA,CAAA,QAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,cAAA,UAAA;AACP,WAAA,YAAA,OAAA,mBAAA,MAAA,sBAAA;AACA,MAAA,OAAA,CAAA,MAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,cAAA,mBAAA,aAAA,YAAA,aAAA,MAAA,wBAAqG,SAAmB,CAAA,MAAA,CAAQ,SAAmB,CAAA,gBAAA,EAAmB,SAAmB,CAAA,gBAAA,EAAmB,SAAmB,CAAA,gBAAA,SAA0B,SAAmB,CAAA,SAAA,CAAW,SAAmB,CAAA,gBAAA,EAAmB,SAAmB,mBAAmB,SAAmB,CAAA,gBAAA;;;;"}
package/dist/index.js CHANGED
@@ -4,10 +4,10 @@ Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var _ = require('lodash');
6
6
  var serverJs = require('@o2ter/server-js');
7
- var validator = require('./internals/validator-B5yHpyvb.js');
7
+ var validator = require('./internals/validator-Bc1jRJfA.js');
8
8
  var _private = require('./internals/private-Ciddhure.js');
9
9
  var utilsJs = require('@o2ter/utils-js');
10
- var index = require('./internals/index-C01HL8O6.js');
10
+ var index = require('./internals/index-vOFh8pVc.js');
11
11
  var index$1 = require('./internals/index-CLKTEIj0.js');
12
12
  var jwt = require('jsonwebtoken');
13
13
  var node_buffer = require('node:buffer');
@@ -327,7 +327,7 @@ class _ProtoQuery extends index.TQuery {
327
327
  yield self._objectMethods(object);
328
328
  });
329
329
  }
330
- _on_upsert(objects) {
330
+ _on_upsert_traggers(objects) {
331
331
  const createTraggers = this._proto[_private.PVK].triggers[this.className]?.create ?? [];
332
332
  const updateTraggers = this._proto[_private.PVK].triggers[this.className]?.update ?? [];
333
333
  for (const obj of objects) {
@@ -342,6 +342,8 @@ class _ProtoQuery extends index.TQuery {
342
342
  })();
343
343
  }
344
344
  }
345
+ }
346
+ _on_upsert(objects) {
345
347
  if (this._proto.schema[this.className]?.liveQuery) {
346
348
  (async () => {
347
349
  try {
@@ -354,7 +356,7 @@ class _ProtoQuery extends index.TQuery {
354
356
  })();
355
357
  }
356
358
  }
357
- _on_delete(objects) {
359
+ _on_delete_traggers(objects) {
358
360
  const traggers = this._proto[_private.PVK].triggers[this.className]?.delete ?? [];
359
361
  for (const obj of objects) {
360
362
  for (const tragger of traggers) {
@@ -368,6 +370,8 @@ class _ProtoQuery extends index.TQuery {
368
370
  })();
369
371
  }
370
372
  }
373
+ }
374
+ _on_delete(objects) {
371
375
  if (this._proto.schema[this.className]?.liveQuery) {
372
376
  (async () => {
373
377
  try {
@@ -386,26 +390,30 @@ class _ProtoQuery extends index.TQuery {
386
390
  matches: this[_private.PVK].options.matches,
387
391
  groupMatches: this[_private.PVK].options.groupMatches,
388
392
  }, values));
389
- if (!options?.silent)
390
- this._on_upsert(objs);
393
+ this._on_upsert(objs);
394
+ if (!options?.silent || !options.master)
395
+ this._on_upsert_traggers(objs);
391
396
  return objs;
392
397
  }
393
398
  async updateMany(update, options) {
394
399
  const objs = this._objectMethods(await this._dispatcher(options).update(this._queryOptions, update));
395
- if (!options?.silent)
396
- this._on_upsert(objs);
400
+ this._on_upsert(objs);
401
+ if (!options?.silent || !options.master)
402
+ this._on_upsert_traggers(objs);
397
403
  return objs;
398
404
  }
399
405
  async upsertMany(update, setOnInsert, options) {
400
406
  const objs = this._objectMethods(await this._dispatcher(options).upsert(this._queryOptions, update, setOnInsert));
401
- if (!options?.silent)
402
- this._on_upsert(objs);
407
+ this._on_upsert(objs);
408
+ if (!options?.silent || !options.master)
409
+ this._on_upsert_traggers(objs);
403
410
  return objs;
404
411
  }
405
412
  async deleteMany(options) {
406
413
  const objs = this._objectMethods(await this._dispatcher(options).delete(this._queryOptions));
407
- if (!options?.silent)
408
- this._on_delete(objs);
414
+ this._on_delete(objs);
415
+ if (!options?.silent || !options.master)
416
+ this._on_delete_traggers(objs);
409
417
  return objs;
410
418
  }
411
419
  }
@@ -1075,14 +1083,14 @@ class ProtoInternal {
1075
1083
  });
1076
1084
  }
1077
1085
  listen(proto, callback) {
1078
- const isMaster = proto.isMaster;
1079
- const roles = isMaster ? [] : this._perms(proto);
1080
1086
  return {
1081
1087
  remove: this.options.pubsub.subscribe(_const.PROTO_NOTY_MSG, payload => {
1082
1088
  const { _rperm } = payload;
1083
1089
  (async () => {
1084
1090
  try {
1085
- if (!isMaster && !_.some(await roles, x => _.includes(_rperm, x)))
1091
+ const isMaster = proto.isMaster;
1092
+ const roles = isMaster ? [] : await this._perms(proto);
1093
+ if (!isMaster && !_.some(roles, x => _.includes(_rperm, x)))
1086
1094
  return;
1087
1095
  await callback(payload);
1088
1096
  }
@@ -1099,18 +1107,17 @@ class ProtoInternal {
1099
1107
  return this.options.pubsub.publish(_const.PROTO_LIVEQUERY_MSG, JSON.parse(index.serialize({ event, objects }, { objAttrs: index$1.TObject.defaultKeys })));
1100
1108
  }
1101
1109
  _liveQuery(proto, callback) {
1102
- const isMaster = proto.isMaster;
1103
- const roles = isMaster ? [] : this._perms(proto);
1104
1110
  return {
1105
1111
  remove: this.options.pubsub.subscribe(_const.PROTO_LIVEQUERY_MSG, payload => {
1106
1112
  const { event, objects } = index.deserialize(JSON.stringify(payload));
1107
1113
  (async () => {
1108
1114
  try {
1109
- const _roles = await roles;
1115
+ const isMaster = proto.isMaster;
1116
+ const roles = isMaster ? [] : await this._perms(proto);
1110
1117
  const payload = proto.rebind(isMaster ? objects : _.filter(objects, object => {
1111
1118
  const acl = object.acl();
1112
1119
  const clp = proto.schema[object.className].classLevelPermissions?.get ?? ['*'];
1113
- return _.some(_roles, x => _.includes(clp, x) && _.includes(acl.read, x));
1120
+ return _.some(roles, x => _.includes(clp, x) && _.includes(acl.read, x));
1114
1121
  }));
1115
1122
  if (!_.isEmpty(payload))
1116
1123
  await callback(event, payload);
@@ -2281,6 +2288,7 @@ var filesRoute = (router, proto) => {
2281
2288
  }
2282
2289
  res.setHeader('Content-Type', file.type);
2283
2290
  res.setHeader('Cache-Control', 'public, max-age=0');
2291
+ res.setHeader('Content-Disposition', 'attachment');
2284
2292
  res.setHeader('ETag', `"${id}"`);
2285
2293
  let stream;
2286
2294
  if (_.isArray(ranges) && ranges.type === 'bytes') {
@@ -2633,42 +2641,37 @@ const ProtoRoute = async (options) => {
2633
2641
  const registerProtoSocket = (proto, server, endpoint) => {
2634
2642
  const io = endpoint ? server.socket().of(endpoint) : server.socket();
2635
2643
  io.on('connection', async (socket) => {
2644
+ let { token } = socket.handshake.auth;
2645
+ const service = await proto.connectWithSessionToken(token);
2646
+ socket.on('auth', (t) => {
2647
+ token = t;
2648
+ service.connectWithSessionToken(t);
2649
+ });
2636
2650
  let events = {};
2637
2651
  let queries = {};
2638
- const connect = (proto) => {
2639
- const { remove: remove_basic } = proto.listen(data => {
2640
- const ids = _.keys(_.pickBy(events, v => v instanceof validator.QuerySelector ? v.eval(data) : v));
2641
- const payload = JSON.parse(index.serialize(data));
2642
- if (!_.isEmpty(ids))
2643
- socket.emit('ON_EV_NOTIFY', { ids, data: payload });
2644
- });
2645
- const { remove: remove_livequery } = proto[_private.PVK]._liveQuery(proto, (ev, objs) => {
2646
- const ids = {};
2647
- for (const obj of objs) {
2648
- ids[obj.id] = _.keys(_.pickBy(queries, v => {
2649
- if (v.event !== ev || v.className !== obj.className)
2650
- return false;
2651
- return v.filter instanceof validator.QuerySelector ? v.filter.eval(obj) : v.filter;
2652
- }));
2653
- }
2654
- if (_.isEmpty(ids))
2655
- return;
2656
- const payload = JSON.parse(index.serialize(_.filter(objs, obj => !_.isEmpty(ids[obj.id]))));
2657
- socket.emit('ON_EV_LIVEQUERY', { ids, data: payload });
2658
- });
2659
- return () => {
2660
- remove_basic();
2661
- remove_livequery();
2662
- };
2663
- };
2664
- const { token } = socket.handshake.auth;
2665
- const service = await proto.connectWithSessionToken(token);
2666
- const remove = connect(service);
2667
- socket.on('auth', (token) => {
2668
- service.connectWithSessionToken(token);
2652
+ const { remove: remove_basic } = service.listen(data => {
2653
+ const ids = _.keys(_.pickBy(events, v => v instanceof validator.QuerySelector ? v.eval(data) : v));
2654
+ const payload = JSON.parse(index.serialize(data));
2655
+ if (!_.isEmpty(ids))
2656
+ socket.emit('ON_EV_NOTIFY', { ids, data: payload });
2657
+ });
2658
+ const { remove: remove_livequery } = service[_private.PVK]._liveQuery(service, (ev, objs) => {
2659
+ const ids = {};
2660
+ for (const obj of objs) {
2661
+ ids[obj.id] = _.keys(_.pickBy(queries, v => {
2662
+ if (v.event !== ev || v.className !== obj.className)
2663
+ return false;
2664
+ return v.filter instanceof validator.QuerySelector ? v.filter.eval(obj) : v.filter;
2665
+ }));
2666
+ }
2667
+ if (_.isEmpty(ids))
2668
+ return;
2669
+ const payload = JSON.parse(index.serialize(_.filter(objs, obj => !_.isEmpty(ids[obj.id]))));
2670
+ socket.emit('ON_EV_LIVEQUERY', { ids, data: payload });
2669
2671
  });
2670
2672
  socket.on('disconnect', () => {
2671
- remove();
2673
+ remove_basic();
2674
+ remove_livequery();
2672
2675
  });
2673
2676
  socket.on('EV_NOTIFY', (payload) => {
2674
2677
  events = _.mapValues(payload, v => {