@live-change/relations-plugin 0.9.19 → 0.9.21

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.
package/boundToAny.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  defineAnyProperties, defineAnyIndex,
3
- processModelsAnyAnnotation, generateAnyId
3
+ processModelsAnyAnnotation, generateAnyId, defineAnyTypeIndexes
4
4
  } from './utilsAny.js'
5
5
 
6
6
  import { defineSetEvent, defineUpdatedEvent, defineTransferredEvent, defineResetEvent } from './propertyEvents.js'
@@ -21,6 +21,7 @@ export default function(service, app) {
21
21
 
22
22
  defineAnyProperties(context.model, context.otherPropertyNames)
23
23
  defineAnyIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
24
+ defineAnyTypeIndexes(config, context, context.otherPropertyNames.length === 1)
24
25
 
25
26
  defineObjectView(config, context,
26
27
  config.singleAccess || config.readAccess || config.singleAccessControl || config.readAccessControl
package/changeTriggers.js CHANGED
@@ -44,11 +44,11 @@ async function iterateChildren(context, propertyName, path, cb) {
44
44
  limit: bucketSize
45
45
  })
46
46
  //console.log("BUCKET", bucket)
47
- if(bucket.length == 0) break
47
+ if(bucket.length === 0) break
48
48
  gt = bucket[bucket.length - 1].id
49
49
  const copyTriggerPromises = bucket.map(entity => cb({ ...entity, id: entity.to }))
50
50
  await Promise.all(copyTriggerPromises)
51
- } while (bucket.length == bucketSize)
51
+ } while (bucket.length === bucketSize)
52
52
  }
53
53
  }
54
54
 
@@ -135,7 +135,7 @@ async function copyObject(context, objectType, object, parentType, parent, ident
135
135
  }
136
136
  for(let i = 0; i < others.length; i++) {
137
137
  const other = others[i]
138
- if(other == parentType) {
138
+ if(other === parentType) {
139
139
  newIdentifiers[otherPropertyNames[i]] = parent
140
140
  }
141
141
  }
package/itemOfAny.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  defineAnyProperties, defineAnyIndexes,
3
3
  processModelsAnyAnnotation, addAccessControlAnyParents, generateAnyId, defineDeleteByOwnerEvents,
4
- defineParentDeleteTrigger
4
+ defineParentDeleteTrigger, defineAnyTypeIndexes
5
5
  } from './utilsAny.js'
6
6
 
7
7
  import {
@@ -26,6 +26,7 @@ export default function(service, app) {
26
26
 
27
27
  addAccessControlAnyParents(context)
28
28
  defineAnyIndexes(context.model, context.otherPropertyNames)
29
+ defineAnyTypeIndexes(config, context, false)
29
30
 
30
31
  if(config.sortBy) {
31
32
  for(const sortFields of config.sortBy) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@live-change/relations-plugin",
3
- "version": "0.9.19",
3
+ "version": "0.9.21",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -22,8 +22,8 @@
22
22
  },
23
23
  "type": "module",
24
24
  "dependencies": {
25
- "@live-change/framework": "^0.9.19",
25
+ "@live-change/framework": "^0.9.21",
26
26
  "pluralize": "^8.0.0"
27
27
  },
28
- "gitHead": "ea1ba1df62d2efac97f43b31aa66b87ec465614a"
28
+ "gitHead": "362e325d1c636f9c0f2fb6432e209c5c56f46919"
29
29
  }
package/propertyOfAny.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  defineAnyProperties, defineAnyIndexes,
3
3
  processModelsAnyAnnotation, generateAnyId, addAccessControlAnyParents,
4
- defineDeleteByOwnerEvents, defineParentDeleteTrigger
4
+ defineDeleteByOwnerEvents, defineParentDeleteTrigger, defineAnyTypeIndexes,
5
5
  } from './utilsAny.js'
6
6
 
7
7
  import {
@@ -37,6 +37,7 @@ export default function(service, app) {
37
37
 
38
38
  addAccessControlAnyParents(context)
39
39
  defineAnyIndexes(context.model, context.otherPropertyNames, false)
40
+ defineAnyTypeIndexes(config, context, context.otherPropertyNames.length === 1)
40
41
 
41
42
  defineObjectView(config, context,
42
43
  config.singleAccess || config.readAccess || config.singleAccessControl || config.readAccessControl
package/relatedToAny.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import {
2
- defineAnyProperties, defineAnyIndex, processModelsAnyAnnotation
2
+ defineAnyProperties, defineAnyIndex, processModelsAnyAnnotation, defineAnyTypeIndexes
3
3
  } from './utilsAny.js'
4
4
 
5
5
  import {
@@ -21,6 +21,7 @@ export default function(service, app) {
21
21
 
22
22
  context.identifiers = defineAnyProperties(context.model, context.otherPropertyNames)
23
23
  defineAnyIndex(context.model, context.joinedOthersClassName, context.otherPropertyNames)
24
+ defineAnyTypeIndexes(config, context, false)
24
25
 
25
26
  if(config.sortBy) {
26
27
  for(const sortFields of config.sortBy) {
package/utilsAny.js CHANGED
@@ -7,7 +7,7 @@ import { allCombinations } from "./combinations.js"
7
7
  import { fireChangeTriggers, registerParentDeleteTriggers } from "./changeTriggers.js"
8
8
 
9
9
 
10
- function extractTypeAndIdParts(otherPropertyNames, properties) {
10
+ export function extractTypeAndIdParts(otherPropertyNames, properties) {
11
11
  const typeAndIdParts = []
12
12
  for (const propertyName of otherPropertyNames) {
13
13
  typeAndIdParts.push(properties[propertyName+'Type'])
@@ -16,7 +16,7 @@ function extractTypeAndIdParts(otherPropertyNames, properties) {
16
16
  return typeAndIdParts
17
17
  }
18
18
 
19
- function extractIdentifiersWithTypes(otherPropertyNames, properties) {
19
+ export function extractIdentifiersWithTypes(otherPropertyNames, properties) {
20
20
  const identifiers = {}
21
21
  for (const propertyName of otherPropertyNames) {
22
22
  identifiers[propertyName] = properties[propertyName]
@@ -25,20 +25,21 @@ function extractIdentifiersWithTypes(otherPropertyNames, properties) {
25
25
  return identifiers
26
26
  }
27
27
 
28
- function generateAnyId(otherPropertyNames, properties) {
28
+ export function generateAnyId(otherPropertyNames, properties) {
29
+ /*
29
30
  console.log("GEN ID", otherPropertyNames, properties, '=>',
30
31
  otherPropertyNames
31
32
  .map(p => [p+'Type', p])
32
33
  .flat()
33
34
  .map(p => JSON.stringify(properties[p])).join(':'))
34
-
35
+ */
35
36
  return otherPropertyNames
36
37
  .map(p => [p+'Type', p])
37
38
  .flat()
38
39
  .map(p => JSON.stringify(properties[p])).join(':')
39
40
  }
40
41
 
41
- function defineAnyProperties(model, names) {
42
+ export function defineAnyProperties(model, names) {
42
43
  const identifiers = {}
43
44
  for (let i = 0; i < names.length; i++) {
44
45
  identifiers[names[i]+'Type'] = new PropertyDefinition({
@@ -56,13 +57,14 @@ function defineAnyProperties(model, names) {
56
57
  return identifiers
57
58
  }
58
59
 
59
- function defineAnyIndex(model, what, props) {
60
+ export function defineAnyIndex(model, what, props) {
60
61
  model.indexes['by' + what] = new IndexDefinition({
61
- property: props.map(prop => [prop+'Type', prop]).flat()
62
+ property: props.map(prop => [prop+'Type', prop]).flat(),
63
+ hash: true
62
64
  })
63
65
  }
64
66
 
65
- function defineAnyIndexes(model, props, fullIndex = true) {
67
+ export function defineAnyIndexes(model, props, fullIndex = true) {
66
68
  const propCombinations = allCombinations(props)
67
69
  for(const propCombination of propCombinations) {
68
70
  if(propCombination.length === props.length && !fullIndex) continue
@@ -71,7 +73,7 @@ function defineAnyIndexes(model, props, fullIndex = true) {
71
73
  }
72
74
  }
73
75
 
74
- function processModelsAnyAnnotation(service, app, annotation, multiple, cb) {
76
+ export function processModelsAnyAnnotation(service, app, annotation, multiple, cb) {
75
77
  if (!service) throw new Error("no service")
76
78
  if (!app) throw new Error("no app")
77
79
 
@@ -148,7 +150,7 @@ function processModelsAnyAnnotation(service, app, annotation, multiple, cb) {
148
150
  }
149
151
  }
150
152
 
151
- function addAccessControlAnyParents(context) {
153
+ export function addAccessControlAnyParents(context) {
152
154
  const { modelRuntime } = context
153
155
  context.model.accessControlParents = async (what) => {
154
156
  const id = what.object
@@ -167,7 +169,7 @@ function addAccessControlAnyParents(context) {
167
169
  )
168
170
  }
169
171
 
170
- function prepareAccessControl(accessControl, names) {
172
+ export function prepareAccessControl(accessControl, names) {
171
173
  if(typeof accessControl == 'object') {
172
174
  accessControl.objects = accessControl.objects ?? ((params) => names.map(name => ({
173
175
  objectType: params[name + 'Type'],
@@ -186,7 +188,7 @@ export function cloneAndPrepareAccessControl(accessControl, names) {
186
188
  return newAccessControl
187
189
  }
188
190
 
189
- function defineDeleteByOwnerEvents(config, context) {
191
+ export function defineDeleteByOwnerEvents(config, context) {
190
192
  const {
191
193
  service, modelRuntime, joinedOthersPropertyName, modelName, modelPropertyName, otherPropertyNames, reverseRelationWord
192
194
  } = context
@@ -225,15 +227,56 @@ function defineDeleteByOwnerEvents(config, context) {
225
227
  }
226
228
  }
227
229
 
228
- function defineParentDeleteTrigger(config, context) {
230
+ export function defineParentDeleteTrigger(config, context) {
229
231
  registerParentDeleteTriggers(context, config)
230
232
  }
231
233
 
232
- export {
233
- extractTypeAndIdParts, extractIdentifiersWithTypes, defineAnyProperties,
234
- defineAnyIndex, defineAnyIndexes,
235
- processModelsAnyAnnotation, generateAnyId,
236
- addAccessControlAnyParents,
237
- prepareAccessControl,
238
- defineDeleteByOwnerEvents, defineParentDeleteTrigger
234
+ export function defineAnyTypeIndexes(config, context, useId = false) {
235
+ const { service, model } = context
236
+ const tableName = service.name + '_' + model.name
237
+ if(useId) { // don't use indexes - only object id's - good for propertyOfAny with one parent
238
+ if(context.otherPossibleTypes[0]?.length) return // types defined in definition - no need for index
239
+ model.indexes[context.otherPropertyNames[0]+'Types'] = new IndexDefinition({
240
+ //property: [propertyName+'Type'],
241
+ function: async function(input, output, { tableName }) {
242
+ const table = await input.table(tableName)
243
+ await table.onChange(async (obj, oldObj) => {
244
+ const id = obj?.id ?? oldObj?.id
245
+ const type = id.slice(0, id.indexOf(':'))
246
+ const count = await table.count({ gte: type+':', lte: type+'_\xFF\xFF\xFF\xFF', limit: 1 })
247
+ if(count > 0) {
248
+ await output.put({ id: JSON.parse(type) })
249
+ } else {
250
+ await output.delete({ id: JSON.parse(type) })
251
+ }
252
+ })
253
+ },
254
+ parameters: { tableName: tableName }
255
+ })
256
+ return
257
+ }
258
+ for(let i = 0; i < context.otherPropertyNames.length; i++) {
259
+ const propertyName = context.otherPropertyNames[i]
260
+ const propertyTypes = context.otherPossibleTypes[i]
261
+ if(propertyTypes.length !== 0) continue // types defined in definition - no need for index
262
+ const srcIndexName = 'by' + propertyName[0].toUpperCase() + propertyName.slice(1)
263
+ if(!model.indexes[srcIndexName]) throw new Error("Parent index not defined: " + srcIndexName)
264
+ model.indexes[propertyName+'Types'] = new IndexDefinition({
265
+ //property: [propertyName+'Type'],
266
+ function: async function(input, output, { indexName }) {
267
+ const index = await input.index(indexName)
268
+ await index.onChange(async (obj, oldObj) => {
269
+ const id = obj?.id ?? oldObj?.id
270
+ const type = id.slice(0, id.indexOf(':'))
271
+ const count = await index.count({ gte: type+':', lte: type+'_\xFF\xFF\xFF\xFF', limit: 1 })
272
+ if(count > 0) {
273
+ await output.put({ id: JSON.parse(type) })
274
+ } else {
275
+ await output.delete({ id: JSON.parse(type) })
276
+ }
277
+ })
278
+ },
279
+ parameters: { indexName: tableName + '_' + srcIndexName }
280
+ })
281
+ }
239
282
  }