From 243604a355a09cbf91cbb96fe782d87270e712d1 Mon Sep 17 00:00:00 2001 From: Ivan S Glazunov Date: Sun, 27 Aug 2023 14:59:16 +0000 Subject: [PATCH 1/2] clientfirst --- imports/client.tsx | 151 ++++++++++++++++++++++++++++++------- imports/minilinks-query.ts | 6 +- imports/minilinks.ts | 91 +++++++++++++++++++++- 3 files changed, 215 insertions(+), 33 deletions(-) diff --git a/imports/client.tsx b/imports/client.tsx index 3ccfb589..1ead5e00 100644 --- a/imports/client.tsx +++ b/imports/client.tsx @@ -24,6 +24,8 @@ corePckg.data.filter(l => !!l.type).forEach((l, i) => { corePckgIds[l.id] = i+1; }); +const random = () => Math.random().toString(36).slice(2, 7); + export const _ids = { '@deep-foundation/core': corePckgIds, }; @@ -139,9 +141,9 @@ export const pathToWhere = (start: (DeepClientStartItem), ...path: DeepClientPat return where; } -export const serializeWhere = (exp: any, env: string = 'links'): any => { +export const serializeWhere = (exp: any, env: string = 'links', unvertualizeId: (id: number) => number = defaultUnvertualizeId): any => { // if exp is array - map - if (Object.prototype.toString.call(exp) === '[object Array]') return exp.map((e) => serializeWhere(e, env)); + if (Object.prototype.toString.call(exp) === '[object Array]') return exp.map((e) => serializeWhere(e, env, unvertualizeId)); else if (typeof(exp) === 'object') { // if object const keys = Object.keys(exp); @@ -162,26 +164,27 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => { setted = result[type] = { value: { _eq: exp[key] } }; } else { // else just equal - setted = result[key] = { _eq: exp[key] }; + setted = result[key] = { _eq: unvertualizeId(exp[key]) }; } } else if (!_boolExpFields[key] && Object.prototype.toString.call(exp[key]) === '[object Array]') { // if field is not boolExp (_and _or _not) but contain array // @ts-ignore - setted = result[key] = serializeWhere(pathToWhere(...exp[key])); + setted = result[key] = serializeWhere(pathToWhere(...exp[key]), 'links', unvertualizeId); } } else if (env === 'tree') { // if field contain primitive type - string/number if (type === 'string' || type === 'number') { - setted = result[key] = { _eq: exp[key] }; + const isId = key === 'link_id' || key === 'tree_id' || key === 'root_id' || key === 'parent_id'; + setted = result[key] = { _eq: isId ? unvertualizeId(exp[key]) : exp[key] }; } else if (!_boolExpFields[key] && Object.prototype.toString.call(exp[key]) === '[object Array]') { // if field is not boolExp (_and _or _not) but contain array // @ts-ignore - setted = result[key] = serializeWhere(pathToWhere(...exp[key])); + setted = result[key] = serializeWhere(pathToWhere(...exp[key]), 'links', unvertualizeId); } } else if (env === 'value') { // if this is value if (type === 'string' || type === 'number') { - setted = result[key] = { _eq: exp[key] }; + setted = result[key] = { _eq: key === 'link_id' ? unvertualizeId(exp[key]) : exp[key] }; } } if (type === 'object' && exp[key].hasOwnProperty('_type_of') && ( @@ -192,7 +195,7 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => { (env === 'value' && key === 'link_id') )) { // if field is object, and contain _type_od - const _temp = setted = { _by_item: { path_item_id: { _eq: exp[key]._type_of }, group_id: { _eq: 0 } } }; + const _temp = setted = { _by_item: { path_item_id: { _eq: unvertualizeId(exp[key]._type_of) }, group_id: { _eq: _ids['@deep-foundation/core'].typesTree } } }; if (key === 'id') { result._and = result._and ? [...result._and, _temp] : [_temp]; } else { @@ -205,8 +208,9 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => { (env === 'tree' && !!~['link_id', 'tree_id', 'root_id', 'parent_id'].indexOf(key)) || (env === 'value' && key === 'link_id') ) && Object.prototype.toString.call(exp[key]._id) === '[object Array]' && exp[key]._id.length >= 1) { - // if field is object, and contain _type_od - const _temp = setted = serializeWhere(pathToWhere(exp[key]._id[0], ...exp[key]._id.slice(1)), 'links'); + const root = exp[key]._id[0]; + // if field is object, and contain _type_of + const _temp = setted = serializeWhere(pathToWhere(typeof(root) === 'number' ? unvertualizeId(root) : root, ...exp[key]._id.slice(1)), 'links', unvertualizeId); if (key === 'id') { result._and = result._and ? [...result._and, _temp] : [_temp]; } else { @@ -220,13 +224,13 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => { _boolExpFields[key] ) ? ( // just parse each item in array - serializeWhere(exp[key], env) + serializeWhere(exp[key], env, unvertualizeId) ) : ( // if we know context _serialize?.[env]?.relations?.[key] ) ? ( // go to this context then - serializeWhere(exp[key], _serialize?.[env]?.relations?.[key]) + serializeWhere(exp[key], _serialize?.[env]?.relations?.[key], unvertualizeId) ) : ( // else just stop exp[key] @@ -242,10 +246,12 @@ export const serializeWhere = (exp: any, env: string = 'links'): any => { } }; -export const serializeQuery = (exp: any, env: string = 'links'): any => { +const defaultUnvertualizeId = (id) => id; + +export const serializeQuery = (exp: any, env: string = 'links', unvertualizeId = defaultUnvertualizeId): any => { const { limit, order_by, offset, distinct_on, ...where } = exp; - const result: any = { where: typeof(exp) === 'object' ? Object.prototype.toString.call(exp) === '[object Array]' ? { id: { _in: exp } } : serializeWhere(where, env) : { id: { _eq: exp } } }; - // const result: any = { where: serializeWhere(where, env) }; + const result: any = { where: typeof(exp) === 'object' ? Object.prototype.toString.call(exp) === '[object Array]' ? { id: { _in: exp.map(id => unvertualizeId(id)) } } : serializeWhere(where, env, unvertualizeId) : { id: { _eq: unvertualizeId(exp) } } }; + // const result: any = { where: serializeWhere(where, env, unvertualizeId) }; if (limit) result.limit = limit; if (order_by) result.order_by = order_by; if (offset) result.offset = offset; @@ -351,7 +357,8 @@ export interface DeepClientInstance> { serializeWhere(exp: any, env?: string): any; - serializeQuery(exp: any, env?: string): any; + serializeQuery(exp: any, env?: string, unvertualizeId?: (id: number) => number): any; + unvertualizeId(id: number): number; id(start: DeepClientStartItem | QueryLink, ...path: DeepClientPathItem[]): Promise; idLocal(start: DeepClientStartItem, ...path: DeepClientPathItem[]): number; @@ -474,6 +481,69 @@ export function checkAndFillShorts(obj) { } } +export function convertDeepInsertToMinilinksApply(deep, objects, table, result: { id?: number; from_id?: number; to_id?: number; type_id?: number; value?: any }[] = []): void { + if (table === 'links') { + for (let i = 0; i < objects.length; i++) { + const o = objects[i]; + let id = o.id; + if (!id) { + id = deep.minilinks.virtualCounter--; + // @ts-ignore + deep.minilinks?.byId[id]?._id = apply; + } + result.push({ + id: o.id || id, from_id: o.from_id, to_id: o.to_id, type_id: o.type_id, + value: o.string?.data || o.number?.data || o.object?.data, + }); + if (o?.from) convertDeepInsertToMinilinksApply(deep, [o?.from?.data], table, result); + if (o?.to) convertDeepInsertToMinilinksApply(deep, [o?.to?.data], table, result); + if (o?.type) convertDeepInsertToMinilinksApply(deep, [o?.type?.data], table, result); + if (o?.out) convertDeepInsertToMinilinksApply(deep, (o?.out?.data?.length ? o?.out?.data : [o?.out?.data]).map(l => ({ ...l, from_id: id })), table, result); + if (o?.in) convertDeepInsertToMinilinksApply(deep, (o?.in?.data?.length ? o?.in?.data : [o?.in?.data]).map(l => ({ ...l, to_id: id })), table, result); + if (o?.types) convertDeepInsertToMinilinksApply(deep, (o?.types?.data?.length ? o?.types?.data : [o?.types?.data]).map(l => ({ ...l, type_id: id })), table, result); + } + } +} + +export function convertDeepUpdateToMinilinksApply(ml, _exp, _set, table, toUpdate: { id?: number; from_id?: number; to_id?: number; type_id?: number; value?: any }[] = []): void { + if (table === 'links') { + try { + const founded = ml.query(_exp); + for (let f of founded) { + toUpdate.push({ + id: f.id, from_id: f.from_id, to_id: f.to_id, type_id: f.type_id, + value: f.value, + ..._set + }); + } + } catch(e) {} + } else if (table === 'strings' || table === 'numbers' || table === 'objects') { + const key = table.slice(0, -1); + const founded = ml.query({ [key]: _exp }); + for (let f of founded) { + toUpdate.push({ + id: f.id, from_id: f.from_id, to_id: f.to_id, type_id: f.type_id, + value: { ...f?.value, value: _set.value }, + }); + } + } +} + +export function convertDeepDeleteToMinilinksApply(ml, _exp, table, toDelete: number[] = [], toUpdate: { id?: number; from_id?: number; to_id?: number; type_id?: number; value?: any }[] = []): void { + if (table === 'links') { + try { + const founded = ml.query(_exp); + toDelete.push(...founded.map(l => l.id)); + } catch(e) {} + } else if (table === 'strings' || table === 'numbers' || table === 'objects') { + const key = table.slice(0, -1); + const founded = ml.query({ [key]: _exp }); + toUpdate.push(...founded.map(o => ({ + id: o.id, from_id: o.from_id, to_id: o.to_id, type_id: o.type_id, + }))); + } +} + export class DeepClient> implements DeepClientInstance { static resolveDependency?: (path: string) => Promise @@ -538,6 +608,10 @@ export class DeepClient> implements DeepClientInstance { // @ts-ignore this.minilinks = options.minilinks || new MinilinkCollection(); + this.unvertualizeId = (id: number): number => { + // @ts-ignore + return this.minilinks.virtual.hasOwnProperty(id) ? this.minilinks.virtual[id] : id; + }; this.table = options.table || 'links'; this.token = options.token; @@ -589,12 +663,13 @@ export class DeepClient> implements DeepClientInstance { serializeQuery = serializeQuery; serializeWhere = serializeWhere; + unvertualizeId: (id: number) => number; async select(exp: Exp, options?: ReadOptions): Promise> { if (!exp) { return { error: { message: '!exp' }, data: undefined, loading: false, networkStatus: undefined }; } - const query = serializeQuery(exp, options?.table || 'links'); + const query = serializeQuery(exp, options?.table || 'links', this.unvertualizeId); const table = options?.table || this.table; const returning = options?.returning ?? (table === 'links' ? this.linksSelectReturning : @@ -635,7 +710,13 @@ export class DeepClient> implements DeepClientInstance { const variables = options?.variables; const name = options?.name || this.defaultInsertName; let q: any = {}; - + + if (this.minilinks) { + const toApply: any = []; + convertDeepInsertToMinilinksApply(this, _objects, table, toApply); + this.minilinks.add(toApply); + } + try { q = await this.apolloClient.mutate(generateSerial({ actions: [insertMutation(table, { ...variables, objects: _objects }, { tableName: table, operation: 'insert', returning })], @@ -646,7 +727,7 @@ export class DeepClient> implements DeepClientInstance { if (sqlError?.message) e.message = sqlError.message; if (!this._silent(options)) throw new Error(`DeepClient Insert Error: ${e.message}`, { cause: e }) return { ...q, data: (q)?.data?.m0?.returning, error: e }; - } + } // @ts-ignore return { ...q, data: (q)?.data?.m0?.returning }; @@ -656,8 +737,15 @@ export class DeepClient> implements DeepClientInstance { if (exp === null) return this.insert( [value], options); if (value === null) return this.delete( exp, options ); - const query = serializeQuery(exp, options?.table === this.table || !options?.table ? 'links' : 'value'); + const query = serializeQuery(exp, options?.table === this.table || !options?.table ? 'links' : 'value', this.unvertualizeId); const table = options?.table || this.table; + + if (this.minilinks) { + const toUpdate: any = []; + convertDeepUpdateToMinilinksApply(this.minilinks, exp, value, table, toUpdate); + this.minilinks.update(toUpdate); + } + const returning = options?.returning || this.updateReturning; const variables = options?.variables; const name = options?.name || this.defaultUpdateName; @@ -673,18 +761,28 @@ export class DeepClient> implements DeepClientInstance { if (!this._silent(options)) throw new Error(`DeepClient Update Error: ${e.message}`, { cause: e }); return { ...q, data: (q)?.data?.m0?.returning, error: e }; } + // @ts-ignore return { ...q, data: (q)?.data?.m0?.returning }; }; async delete(exp: Exp, options?: WriteOptions):Promise> { if (!exp) throw new Error('!exp'); - const query = serializeQuery(exp, options?.table === this.table || !options?.table ? 'links' : 'value'); + const query = serializeQuery(exp, options?.table === this.table || !options?.table ? 'links' : 'value', this.unvertualizeId); const table = options?.table || this.table; const returning = options?.returning || this.deleteReturning; const variables = options?.variables; const name = options?.name || this.defaultDeleteName; let q; + + if (this.minilinks) { + const toDelete: any = []; + const toUpdate: any = []; + convertDeepDeleteToMinilinksApply(this.minilinks, exp, table, toDelete, toUpdate); + this.minilinks.update(toUpdate); + this.minilinks.remove(toDelete); + } + try { q = await this.apolloClient.mutate(generateSerial({ actions: [deleteMutation(table, { ...variables, ...query, returning }, { tableName: table, operation: 'delete', returning })], @@ -697,6 +795,7 @@ export class DeepClient> implements DeepClientInstance { if (!this._silent(options)) throw new Error(`DeepClient Delete Error: ${e.message}`, { cause: e }); return { ...q, data: (q)?.data?.m0?.returning, error: e }; } + return { ...q, data: (q)?.data?.m0?.returning }; }; @@ -730,7 +829,7 @@ export class DeepClient> implements DeepClientInstance { const newSerialActions: IGenerateMutationBuilder[] = updateOperations.map(operation => { const exp = operation.exp; const value = operation.value; - const query = serializeQuery(exp, table === this.table || !table ? 'links' : 'value'); + const query = serializeQuery(exp, table === this.table || !table ? 'links' : 'value', this.unvertualizeId); return updateMutation(table, {...query, _set: value }, { tableName: table, operation: operationType ,returning}) }) serialActions = [...serialActions, ...newSerialActions]; @@ -738,7 +837,7 @@ export class DeepClient> implements DeepClientInstance { const deleteOperations = operations as Array>>;; const newSerialActions: IGenerateMutationBuilder[] = deleteOperations.map(operation => { const exp = operation.exp; - const query = serializeQuery(exp, table === this.table || !table ? 'links' : 'value'); + const query = serializeQuery(exp, table === this.table || !table ? 'links' : 'value', this.unvertualizeId); return deleteMutation(table, { ...query }, { tableName: table, operation: operationType, returning }) }) serialActions = [...serialActions, ...newSerialActions]; @@ -1070,11 +1169,11 @@ export function useDeepQuery { - const sq = serializeQuery(query); + const sq = serializeQuery(query, 'links', deep.unvertualizeId); return generateQuery({ operation: 'query', queries: [generateQueryData({ @@ -1114,7 +1213,7 @@ export function useDeepSubscription
{ - const sq = serializeQuery(query); + const sq = serializeQuery(query, 'links', deep.unvertualizeId); return generateQuery({ operation: 'subscription', queries: [generateQueryData({ diff --git a/imports/minilinks-query.ts b/imports/minilinks-query.ts index f881a1bb..14f7be0a 100644 --- a/imports/minilinks-query.ts +++ b/imports/minilinks-query.ts @@ -1,4 +1,4 @@ -import { _serialize, _boolExpFields, serializeWhere, serializeQuery } from './client.js'; +import { _serialize, _boolExpFields, serializeWhere, serializeQuery, useDeep } from './client.js'; import { BoolExpLink, ComparasionType, QueryLink } from './client_types.js'; import { MinilinkCollection, MinilinksGeneratorOptions, Link } from './minilinks.js'; @@ -12,7 +12,7 @@ export const minilinksQuery = >( ): L[] => { if (typeof(query) === 'number') return [ml.byId[query]]; else { - const q = serializeQuery(query); + const q = serializeQuery(query, 'links'); const result = minilinksQueryHandle(q.where, ml); return q.limit ? result.slice(q.offset || 0, (q.offset || 0) + (q.limit)) : result; } @@ -24,7 +24,7 @@ export const minilinksQueryIs = >( ): boolean => { if (typeof(query) === 'number') return link.id === query; else { - const q = serializeQuery(query); + const q = serializeQuery(query, 'links'); return minilinksQueryLevel( q, link, diff --git a/imports/minilinks.ts b/imports/minilinks.ts index 556f6425..efe6e514 100644 --- a/imports/minilinks.ts +++ b/imports/minilinks.ts @@ -40,9 +40,14 @@ export interface LinkHashFields { [key: string|number]: any; } -export interface Link extends LinkPlain, LinkRelations>, LinkHashFields {} +export interface Link extends LinkPlain, LinkRelations>, LinkHashFields { + _id?: number; + displayId: number; +} export interface MinilinksResult { + virtual: { [id: number]: number }; + virtualCounter: number; links: Link[]; types: { [id: number]: Link[] }; byId: { [id: number]: Link }; @@ -65,10 +70,15 @@ export interface MinilinksResult { errors?: MinilinkError[]; anomalies?: MinilinkError[]; } + update(linksArray: any[]): { + errors?: MinilinkError[]; + anomalies?: MinilinkError[]; + } } export class MinilinksLink { ml?: MinilinkCollection; + _id: Ref; id: Ref; type_id: Ref; from_id?: Ref; @@ -109,6 +119,9 @@ export class MinilinksLink { get to(): MinilinksLink[] { return this.ml?.byId?.[this.to_id]; } + get displayId(): number { + return this._id || this.id; + } value?: any; string?: any; number?: any; @@ -124,7 +137,7 @@ export class MinilinksLink { } toPlain(): LinkPlain { return { - id: this.id, + id: this._id || this.id, type_id: this.type_id, from_id: this.from_id, to_id: this.to_id, @@ -195,6 +208,8 @@ export class MinilinkCollection Number(i)) }, + ...(link.type_id ? { type_id: link.type_id } : {}), + ...(link.from_id ? { from_id: link.from_id } : {}), + ...(link.to_id ? { to_id: link.to_id } : {}), + ...(link.value ? { value: link.value } : {}), + }); + if (virtual) { + if (old) throw new Error(`somehow we have oldLink.id ${old.id} and virtualLink.id ${virtual.id} virtualLink._id = ${virtual._id}`); + old = virtual; + this.virtual[virtual.id] = link.id; + virtual._id = link.id; + link = { ...link, _id: link.id, id: virtual.id }; + } + if (!old) { link._applies = [applyName]; this.emitter.emit('apply', old, link); @@ -455,6 +491,53 @@ export class MinilinkCollection Number(i)) }, + ...(link.type_id ? { type_id: link.type_id } : {}), + ...(link.from_id ? { from_id: link.from_id } : {}), + ...(link.to_id ? { to_id: link.to_id } : {}), + ...(link.value ? { value: link.value } : {}), + }); + if (virtual) { + if (old) throw new Error(`somehow we have oldLink.id ${old.id} and virtualLink.id ${virtual.id} virtualLink._id = ${virtual._id}`); + old = virtual; + virtual._id = link.id; + link = { ...link, _id: link.id, id: virtual.id }; + } + + if (old) { + if (!options.equal(old, link)) { + toUpdate.push(link); + beforeUpdate[link.id] = old; + } + } + _byId[link.id] = link; + } + this._updating = true; + const r2 = this.remove(toUpdate.map(l => l[options.id])); + const a2 = this.add(toUpdate); + for (let i = 0; i < toUpdate.length; i++) { + const l = toUpdate[i]; + this.emitter.emit('updated', beforeUpdate[l.id], byId[l.id]); + } + this._updating = false; + return { errors: [...r2.errors, ...a2.errors], anomalies: [...r2.anomalies, ...a2.anomalies] }; + } constructor(options?: MGO, memory?: any) { const _options = options || MinilinksGeneratorOptionsDefault; this.types = this.byType = memory?.types || {}; From cbfd9439bf73fdc1df86e9b45641785b4bfac704 Mon Sep 17 00:00:00 2001 From: Ivan S Glazunov Date: Mon, 9 Oct 2023 16:46:49 +0000 Subject: [PATCH 2/2] rebase main --- .github/workflows/dockerize.yaml | 2 +- .nvmrc | 2 +- Dockerfile | 2 +- imports/client.tsx | 12 +++---- imports/packager.ts | 4 +-- migrations/1655979260869-sync-handlers.ts | 8 ++--- .../1693460330175-sync-handlers-update.ts | 31 ------------------- package-lock.json | 2 +- package.json | 7 ++--- 9 files changed, 17 insertions(+), 53 deletions(-) delete mode 100644 migrations/1693460330175-sync-handlers-update.ts diff --git a/.github/workflows/dockerize.yaml b/.github/workflows/dockerize.yaml index d1edc3da..8ca9a3ce 100644 --- a/.github/workflows/dockerize.yaml +++ b/.github/workflows/dockerize.yaml @@ -23,7 +23,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-node@v1 with: - node-version: 18 + node-version: '16.20' - name: ci run: npm ci - name: build diff --git a/.nvmrc b/.nvmrc index 3c032078..3876fd49 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -18 +18.16.1 diff --git a/Dockerfile b/Dockerfile index b239a45c..7266d7da 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:18-alpine3.17 AS node +FROM node:18.16.1-alpine3.17 AS node FROM docker:20.10.8-dind-alpine3.14 COPY --from=node /usr/lib /usr/lib diff --git a/imports/client.tsx b/imports/client.tsx index 1ead5e00..e9095202 100644 --- a/imports/client.tsx +++ b/imports/client.tsx @@ -349,8 +349,6 @@ export interface DeepClientInstance> { delete(exp: Exp, options?: WriteOptions):Promise>; - serial(options: AsyncSerialParams): Promise>; - reserve(count: number): Promise; await(id: number): Promise; @@ -372,8 +370,6 @@ export interface DeepClientInstance> { logout(): Promise; can(objectIds: number[], subjectIds: number[], actionIds: number[]): Promise; - - useDeepSubscription: typeof useDeepSubscription } export interface DeepClientAuthResult { @@ -799,7 +795,9 @@ export class DeepClient> implements DeepClientInstance { return { ...q, data: (q)?.data?.m0?.returning }; }; - async serial({ + async serial< + LL = L + >({ name, operations, returning, silent }: AsyncSerialParams): Promise> { // @ts-ignore @@ -1070,14 +1068,14 @@ export class DeepClient> implements DeepClientInstance { try { return await DeepClient.resolveDependency(path); } catch (e) { - console.log(`IGNORED ERROR: Call to DeepClient.resolveDependency is failed with`, e); + console.log(`Call to DeepClient.resolveDependency is failed with`, e); } } if (typeof require !== 'undefined') { try { return await require(path); } catch (e) { - console.log(`IGNORED ERROR: Call to require is failed with`, e); + console.log(`Call to require is failed with`, e); } } return await import(path); diff --git a/imports/packager.ts b/imports/packager.ts index 6b56bf6a..0f18b570 100644 --- a/imports/packager.ts +++ b/imports/packager.ts @@ -278,7 +278,7 @@ export class Packager> { let newId; if (item.package) { newId = await this.client.id(pckg?.dependencies?.[item?.package?.dependencyId]?.name, item.package.containValue, true); - if (!newId) pckg.errors.push(`dependency [${pckg?.dependencies?.[item?.package?.dependencyId]?.name} ${item.package.containValue}], not found`); + if (!newId) pckg.errors.push(`dependency [${pckg?.dependencies?.[item?.package?.dependencyId]?.name, item.package.containValue}], not founded`); } else if (item.type) { newId = ids[idsIndex++]; } @@ -371,7 +371,7 @@ export class Packager> { const ids = await this.client.reserve(counter); const { global, difference } = await this.globalizeIds(pckg, ids, sorted); if (pckg.errors?.length) { - return { errors: pckg.errors }; + return { errors }; } await this.insertItems(pckg, global, counter, dependedLinks, errors, mutated); if (errors.length) return { errors }; diff --git a/migrations/1655979260869-sync-handlers.ts b/migrations/1655979260869-sync-handlers.ts index 016918fd..44aba7b4 100644 --- a/migrations/1655979260869-sync-handlers.ts +++ b/migrations/1655979260869-sync-handlers.ts @@ -334,7 +334,7 @@ const prepareFunction = /*javascript*/` const selectValueTable = `\`SELECT * FROM \${table} WHERE link_id = \${linkId}\``; const selectLinkByValue = `\`SELECT link_id as id FROM \${table} WHERE value = '\${value}'::\${table==='strings' ? 'text' : table==='objects' ? 'jsonb' : 'bigint'}\``; -const generateSelectWhereCode = /*javascript*/`(_where, shift = 0) => { +const generateSelectWhereCode = /*javascript*/`(_where) => { const where = []; let values = []; let valueTable; @@ -557,7 +557,7 @@ const deepFabric = /*javascript*/`(ownerId, hasura_session) => { const findLinkIdByValue = ${findLinkIdByValueCode}; const fillValueByLinks = ${fillValueByLinksCode}; const isDeepEqual = ${isDeepEqualCode}; - let generated = generateSelectWhere(_where, 1); + let generated = generateSelectWhere(_where); const where = generated.where; let links = []; const valueTableString = generated.valueTable ? generated.valueTable === 'values' ? ' left join "strings" on "strings".link_id = "main".id left join "objects" on "objects".link_id = "main".id left join "numbers" on "numbers".link_id = "main".id' : ' left join "'.concat(generated.valueTable, '" on "',generated.valueTable,'".link_id = "main".id') : ''; @@ -569,7 +569,7 @@ const deepFabric = /*javascript*/`(ownerId, hasura_session) => { if (options?.table === 'tree'){ const { id, link_id, parent_id, depth, root_id, position_id, tree_id } = _where; const generateSelectWhere = ${generateSelectWhereCode}; - let generated = generateSelectWhere(_where, 1); + let generated = generateSelectWhere(_where); const where = generated.where; let links = []; if (where) links = plv8.execute(${selectTreeWithPermissions}, [ this.linkId, ...generated.values ]); @@ -795,14 +795,12 @@ const triggerFunctionFabric = (handleOperationTypeId, valueTrigger) => /*javascr `; const deepClientFunction = /*javascript*/` - const checkInsertPermission = ${checkInsertPermissionCode}; const checkUpdatePermission = ${checkUpdatePermissionCode}; const checkDeleteLinkPermission = ${checkDeleteLinkPermissionCode}; const hasura_session = JSON.parse(plv8.execute("select current_setting('hasura.user', 't')")[0].current_setting); const default_role = hasura_session['x-hasura-role']; const default_user_id = hasura_session['x-hasura-user-id']; - const deep = (${deepFabric})(Number(clientlinkid), hasura_session); const result = operation === 'id' || operation === 'update' || operation === 'objectSet' || operation === 'objectGet' ? deep[operation](...args) : operation === 'unsafe' ? deep[operation].plv8.execute(...args) : deep[operation](args, options); if (hasura_session['x-hasura-role'] !== default_role || hasura_session['x-hasura-user-id'] !== default_user_id){ diff --git a/migrations/1693460330175-sync-handlers-update.ts b/migrations/1693460330175-sync-handlers-update.ts deleted file mode 100644 index f4d6cbee..00000000 --- a/migrations/1693460330175-sync-handlers-update.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { createPrepareFunction, createDeepClientFunction, createSyncInsertTriggerFunction, createSyncDeleteTriggerFunction, createSyncUpdateTriggerFunction, createSyncDeleteStringsTriggerFunction, createSyncInsertStringsTriggerFunction, createSyncUpdateStringsTriggerFunction, createSyncDeleteNumbersTriggerFunction, createSyncInsertNumbersTriggerFunction, createSyncUpdateNumbersTriggerFunction, createSyncDeleteObjectsTriggerFunction, createSyncInsertObjectsTriggerFunction, createSyncUpdateObjectsTriggerFunction } from "../migrations/1655979260869-sync-handlers.js"; -import Debug from 'debug'; -import { api } from '../migrations/1616701513782-links.js'; -import { sql } from '@deep-foundation/hasura/sql.js'; - -const debug = Debug('deeplinks:migrations:plv8'); -const log = debug.extend('log'); - - -export const up = async () => { - log('up'); - - await api.sql(createPrepareFunction); - await api.sql(createDeepClientFunction); - await api.sql(createSyncInsertTriggerFunction); - await api.sql(createSyncUpdateTriggerFunction); - await api.sql(createSyncDeleteTriggerFunction); - await api.sql(createSyncInsertStringsTriggerFunction); - await api.sql(createSyncUpdateStringsTriggerFunction); - await api.sql(createSyncDeleteStringsTriggerFunction); - await api.sql(createSyncInsertNumbersTriggerFunction); - await api.sql(createSyncUpdateNumbersTriggerFunction); - await api.sql(createSyncDeleteNumbersTriggerFunction); - await api.sql(createSyncInsertObjectsTriggerFunction); - await api.sql(createSyncUpdateObjectsTriggerFunction); - await api.sql(createSyncDeleteObjectsTriggerFunction); -}; - -export const down = async () => { - log('down'); -}; diff --git a/package-lock.json b/package-lock.json index 243a939b..b3693562 100644 --- a/package-lock.json +++ b/package-lock.json @@ -70,7 +70,7 @@ "webpack-cli": "^5.1.1" }, "engines": { - "node": "^18" + "node": "^18.16.1" }, "peerDependencies": { "@apollo/client": "^3.7.14", diff --git a/package.json b/package.json index bcf4a14c..43535520 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,8 @@ "benchmark": "export DEEPLINKS_HASURA_PATH=localhost:8080; export DEEPLINKS_HASURA_SSL=0; export DEEPLINKS_HASURA_SECRET=myadminsecretkey; ts-node benchmarks/index.ts", "migrate": "npm run package:build && npx migrate@latest up --matches '*.js'", "unmigrate": "npm run package:build && npx migrate@latest down --matches '*.js'", - "migrate-s-h": "npm run package:build && npx migrate@latest up 1693460330175-sync-handlers-update --matches '*.js'", - "unmigrate-s-h": "npm run package:build && npx migrate@latest down 1693460330175-sync-handlers-update --matches '*.js'", - "remigrate-s-h": "npm run unmigrate-s-h && npm run migrate", + "migrate-s-h": "npm run package:build && npx migrate@latest up 1655979260869-sync-handlers --matches '*.js'", + "unmigrate-s-h": "npm run package:build && npx migrate@latest down 1655979260869-sync-handlers --matches '*.js'", "start-engine-docker": "npm run start-engine-docker-core", "start-engine-docker-core": "cd ./node_modules/@deep-foundation/hasura && npm run docker", "stop-engine-docker": "cd ./node_modules/@deep-foundation/hasura/local && docker-compose --project-name deep down", @@ -91,7 +90,7 @@ "react": "^18.0.0" }, "engines": { - "node": "^18" + "node": "^18.16.1" }, "devDependencies": { "@testing-library/jest-dom": "^5.16.5",