diff --git a/src/core/ArSyncStore.ts b/src/core/ArSyncStore.ts index 2e0639a..af5053e 100644 --- a/src/core/ArSyncStore.ts +++ b/src/core/ArSyncStore.ts @@ -1,5 +1,7 @@ import ArSyncApi from './ArSyncApi' -export type Request = { api: string; query: any; params?: any; id?: any } +export type Request = { api: string; query: any; params?: any; id?: IDType } + +type IDType = number | string class ModelBatchRequest { timer: number | null = null @@ -7,8 +9,8 @@ class ModelBatchRequest { Map void @@ -18,7 +20,7 @@ class ModelBatchRequest { } > >() - fetch(api: string, query, id: number) { + fetch(api: string, query, id: IDType) { this.setTimer() return new Promise((resolve, reject) => { const queryJSON = JSON.stringify(query) @@ -68,7 +70,7 @@ type ParsedQuery = { params: any } | {} -type SyncField = { id: number; keys: string[] } +type SyncField = { id: IDType; keys: string[] } type Unsubscribable = { unsubscribe: () => void } class ArSyncContainerBase { @@ -227,12 +229,12 @@ class ArSyncContainerBase { type NotifyData = { action: 'add' | 'remove' | 'update' class: string - id: number + id: IDType field?: string } class ArSyncRecord extends ArSyncContainerBase { - id: number + id: IDType root: ArSyncStore query queryAttributes @@ -426,7 +428,7 @@ class ArSyncCollection extends ArSyncContainerBase { data: any[] children: ArSyncRecord[] aliasOrderKey = 'id' - fetching = new Set() + fetching = new Set() constructor(parentSyncKeys: string[], path: string, query, data: any[], request, root: ArSyncStore, parentModel: ArSyncRecord | null, parentKey: string | null){ super() this.root = root @@ -466,7 +468,7 @@ class ArSyncCollection extends ArSyncContainerBase { } replaceData(data: any[] | { collection: any[]; ordering: Ordering }, parentSyncKeys: string[]) { this.setSyncKeys(parentSyncKeys) - const existings = new Map() + const existings = new Map() for (const child of this.children) existings.set(child.id, child) let collection: any[] if (Array.isArray(data)) { @@ -502,7 +504,7 @@ class ArSyncCollection extends ArSyncContainerBase { for (const el of newData) this.data.push(el) this.subscribeAll() } - consumeAdd(className: string, id: number) { + consumeAdd(className: string, id: IDType) { const { first, last, direction } = this.ordering const limit = first || last if (this.children.find(a => a.id === id)) return @@ -585,7 +587,7 @@ class ArSyncCollection extends ArSyncContainerBase { this.data.sort((a, b) => a[orderKey] > b[orderKey] ? -1 : +1) } } - consumeRemove(id: number) { + consumeRemove(id: IDType) { const idx = this.children.findIndex(a => a.id === id) this.fetching.delete(id) // To cancel consumeAdd if (idx < 0) return @@ -610,7 +612,7 @@ class ArSyncCollection extends ArSyncContainerBase { super.onChange(path, data) if (path[1] === this.aliasOrderKey) this.markAndSort() } - markAndSet(id: number, data) { + markAndSet(id: IDType, data) { this.mark() const idx = this.children.findIndex(a => a.id === id) if (idx >= 0) this.data[idx] = data diff --git a/test/model.rb b/test/model.rb index e80b0c0..9add4db 100644 --- a/test/model.rb +++ b/test/model.rb @@ -17,6 +17,9 @@ class User < BaseRecord end class Post < BaseRecord + before_validation do + self.id ||= '%08d' % (Post.maximum(:id).to_i + 1) + end self.table_name = :posts belongs_to :user has_many :comments, dependent: :destroy diff --git a/test/seed.rb b/test/seed.rb index 3af779f..54eaaaf 100644 --- a/test/seed.rb +++ b/test/seed.rb @@ -8,7 +8,7 @@ create_table :users do |t| t.string :name end - create_table :posts do |t| + create_table :posts, id: :string do |t| t.references :user t.string :title t.text :body @@ -16,7 +16,7 @@ end create_table :comments do |t| - t.references :post + t.references :post, type: :string t.references :user t.text :body t.timestamps @@ -36,7 +36,7 @@ user_ids = User.ids posts = 16.times.map do |i| - { user_id: user_ids.sample, title: "Post#{i}", body: "post #{i}" } + { id: '%08d' % (i + 1), user_id: user_ids.sample, title: "Post#{i}", body: "post #{i}" } end Post.import posts post_ids = Post.ids diff --git a/test/sync_test.rb b/test/sync_test.rb index dc5e06d..a575d6d 100644 --- a/test/sync_test.rb +++ b/test/sync_test.rb @@ -180,7 +180,7 @@ class Schema runner.eval_script <<-JAVASCRIPT global.postModel = new ArSyncModel({ api: 'post', - params: { id: #{post.id} }, + params: { id: #{post.id.to_json} }, query: { comments: { params: { orderBy: 'body', direction: '#{direction}' }, @@ -214,7 +214,7 @@ class Schema runner.eval_script <<-JAVASCRIPT global.postModel = new ArSyncModel({ api: 'post', - params: { id: #{post.id} }, + params: { id: #{post.id.to_json} }, query: { comments: { params: { #{first_last}: 3, direction: '#{direction}' }, @@ -295,7 +295,7 @@ class Schema runner.eval_script <<~JAVASCRIPT global.postModel = new ArSyncModel({ api: 'post', - params: { id: #{post.id} }, + params: { id: #{post.id.to_json} }, query: ['id','titleChars'] }) JAVASCRIPT @@ -315,7 +315,7 @@ class Schema runner.eval_script <<~JAVASCRIPT global.postModel = new ArSyncModel({ api: 'post', - params: { id: #{post.id} }, + params: { id: #{post.id.to_json} }, query: { comments: 'editedStarCount' } }) JAVASCRIPT @@ -333,7 +333,7 @@ class Schema runner.eval_script <<~JAVASCRIPT global.postsModel = new ArSyncModel({ api: 'Post', - params: { ids: [#{post1.id}, #{post2.id}] }, + params: { ids: [#{post1.id.to_json}, #{post2.id.to_json}] }, query: ['id', 'title'] }) JAVASCRIPT @@ -348,8 +348,8 @@ class Schema post1 = Post.first post2 = Post.second runner.eval_script <<~JAVASCRIPT - global.p1 = new ArSyncModel({ api: 'Post', id: #{post1.id}, query: 'title' }) - global.p2 = new ArSyncModel({ api: 'Post', id: #{post2.id}, query: 'title' }) + global.p1 = new ArSyncModel({ api: 'Post', id: #{post1.id.to_json}, query: 'title' }) + global.p2 = new ArSyncModel({ api: 'Post', id: #{post2.id.to_json}, query: 'title' }) JAVASCRIPT runner.assert_script 'p1.data && p2.data' runner.assert_script '[p1.data.title, p2.data.title]', to_be: [post1.title, post2.title] @@ -401,8 +401,8 @@ class Schema runner.eval_script <<~JAVASCRIPT global.data1 = {} global.data2 = {} - ArSyncApi.syncFetch({ api: 'Post', id: #{post.id}, query: 'title' }).then(data => { global.data1 = data }) - ArSyncApi.fetch({ api: 'Post', id: #{post.id}, query: 'title' }).then(data => { global.data2 = data }) + ArSyncApi.syncFetch({ api: 'Post', id: #{post.id.to_json}, query: 'title' }).then(data => { global.data1 = data }) + ArSyncApi.fetch({ api: 'Post', id: #{post.id.to_json}, query: 'title' }).then(data => { global.data2 = data }) JAVASCRIPT runner.assert_script 'data1.title', to_be: post.title runner.assert_script 'data2.title', to_be: post.title diff --git a/test/type_test.ts b/test/type_test.ts index e166533..d351232 100644 --- a/test/type_test.ts +++ b/test/type_test.ts @@ -27,7 +27,7 @@ isOK>() const data3 = new ArSyncModel({ api: 'currentUser', query: '*' }).data! isOK>() const data4 = new ArSyncModel({ api: 'currentUser', query: { posts: 'id' } }).data! -isOK>() +isOK>() const data5 = new ArSyncModel({ api: 'currentUser', query: { posts: '*' } }).data! data5.posts[0].id; data5.posts[0].user; data5.posts[0].body isOK>() @@ -46,11 +46,11 @@ isOK>() const data12 = new ArSyncModel({ api: 'currentUser', query: { posts: { params: { first: 4 }, attributes: 'title' } } }).data! isOK>() const data13 = new ArSyncModel({ api: 'currentUser', query: { posts: { params: { first: 4 }, attributes: ['id', 'title'] } } }).data! -isOK>() +isOK>() const data14 = new ArSyncModel({ api: 'currentUser', query: { posts: { params: { first: 4 }, attributes: { id: true, title: true } } } }).data! -isOK>() +isOK>() const data15 = new ArSyncModel({ api: 'currentUser', query: { posts: ['id', 'title'] } } as const).data! -isOK>() +isOK>() const data16 = new ArSyncModel({ api: 'User', id: 1, query: 'name' }).data! isOK>() const data17 = new ArSyncModel({ api: 'currentUser', query: 'postOrNull' }).data! @@ -62,6 +62,6 @@ isOK>() +isOK>() let digTitle = model.dig(['posts', 0, 'title'] as const) isOK>()