@@ -72,14 +72,18 @@ export const publishNode = async ({
7272 const context = await getSupabaseContext ( plugin ) ;
7373 if ( ! context ) throw new Error ( "Cannot get context" ) ;
7474 const spaceId = context . spaceId ;
75- const myGroupResponse = await client
75+ const myGroupsResponse = await client
7676 . from ( "group_membership" )
7777 . select ( "group_id" ) ;
78- if ( myGroupResponse . error ) throw myGroupResponse . error ;
79- const myGroup = myGroupResponse . data [ 0 ] ?. group_id ;
80- if ( ! myGroup ) throw new Error ( "Cannot get group" ) ;
78+ if ( myGroupsResponse . error ) throw myGroupsResponse . error ;
79+ const myGroups = new Set (
80+ myGroupsResponse . data . map ( ( { group_id } ) => group_id ) ,
81+ ) ;
82+ if ( myGroups . size === 0 ) throw new Error ( "Cannot get group" ) ;
8183 const existingPublish =
8284 ( frontmatter . publishedToGroups as undefined | string [ ] ) || [ ] ;
85+ const commonGroups = existingPublish . filter ( ( g ) => myGroups . has ( g ) ) ;
86+ const myGroup = ( commonGroups . length > 0 ? commonGroups : [ ...myGroups ] ) [ 0 ] ! ;
8387 const idResponse = await client
8488 . from ( "Content" )
8589 . select ( "last_modified" )
@@ -111,63 +115,87 @@ export const publishNode = async ({
111115 ...attachments . map ( ( a ) => a . stat . mtime ) ,
112116 ) ;
113117
114- if ( existingPublish . includes ( myGroup ) && lastModified <= lastModifiedDb )
115- return ; // already published
116- const publishSpaceResponse = await client . from ( "SpaceAccess" ) . upsert (
117- {
118- /* eslint-disable @typescript-eslint/naming-convention */
119- account_uid : myGroup ,
120- space_id : spaceId ,
121- /* eslint-enable @typescript-eslint/naming-convention */
122- permissions : "partial" ,
123- } ,
124- { ignoreDuplicates : true } ,
125- ) ;
126- if ( publishSpaceResponse . error && publishSpaceResponse . error . code !== "23505" )
127- // 23505 is duplicate key, which counts as a success.
128- throw publishSpaceResponse . error ;
118+ const skipPublishAccess =
119+ commonGroups . length > 0 && lastModified <= lastModifiedDb ;
129120
130- const publishResponse = await client . from ( "ResourceAccess" ) . upsert (
131- {
132- /* eslint-disable @typescript-eslint/naming-convention */
133- account_uid : myGroup ,
134- source_local_id : nodeId ,
135- space_id : spaceId ,
136- /* eslint-enable @typescript-eslint/naming-convention */
137- } ,
138- { ignoreDuplicates : true } ,
139- ) ;
140- if ( publishResponse . error && publishResponse . error . code !== "23505" )
141- // 23505 is duplicate key, which counts as a success.
142- throw publishResponse . error ;
121+ if ( ! skipPublishAccess ) {
122+ const publishSpaceResponse = await client . from ( "SpaceAccess" ) . upsert (
123+ {
124+ /* eslint-disable @typescript-eslint/naming-convention */
125+ account_uid : myGroup ,
126+ space_id : spaceId ,
127+ /* eslint-enable @typescript-eslint/naming-convention */
128+ permissions : "partial" ,
129+ } ,
130+ { ignoreDuplicates : true } ,
131+ ) ;
132+ if (
133+ publishSpaceResponse . error &&
134+ publishSpaceResponse . error . code !== "23505"
135+ )
136+ throw publishSpaceResponse . error ;
137+
138+ const publishResponse = await client . from ( "ResourceAccess" ) . upsert (
139+ {
140+ /* eslint-disable @typescript-eslint/naming-convention */
141+ account_uid : myGroup ,
142+ source_local_id : nodeId ,
143+ space_id : spaceId ,
144+ /* eslint-enable @typescript-eslint/naming-convention */
145+ } ,
146+ { ignoreDuplicates : true } ,
147+ ) ;
148+ if ( publishResponse . error && publishResponse . error . code !== "23505" )
149+ throw publishResponse . error ;
143150
144- // Also publish the schema so it's accessible when importing nodes
145- const nodeTypeId = frontmatter . nodeTypeId as string | undefined ;
146- if ( nodeTypeId ) {
147- await publishSchema ( {
148- client ,
149- spaceId ,
150- nodeTypeId ,
151- groupId : myGroup ,
152- } ) ;
151+ const nodeTypeId = frontmatter . nodeTypeId as string | undefined ;
152+ if ( nodeTypeId ) {
153+ await publishSchema ( {
154+ client ,
155+ spaceId ,
156+ nodeTypeId ,
157+ groupId : myGroup ,
158+ } ) ;
159+ }
153160 }
154161
162+ // Always sync non-text assets when node is published to this group
155163 const existingFiles : string [ ] = [ ] ;
164+ const existingReferencesReq = await client
165+ . from ( "FileReference" )
166+ . select ( "*" )
167+ . eq ( "space_id" , spaceId )
168+ . eq ( "source_local_id" , nodeId ) ;
169+ if ( existingReferencesReq . error ) {
170+ console . error ( existingReferencesReq . error ) ;
171+ return ;
172+ }
173+ const existingReferencesByPath = Object . fromEntries (
174+ existingReferencesReq . data . map ( ( ref ) => [ ref . filepath , ref ] ) ,
175+ ) ;
176+
156177 for ( const attachment of attachments ) {
157178 const mimetype = mime . lookup ( attachment . path ) || "application/octet-stream" ;
158179 if ( mimetype . startsWith ( "text/" ) ) continue ;
159180 existingFiles . push ( attachment . path ) ;
160- const content = await plugin . app . vault . readBinary ( attachment ) ;
161- await addFile ( {
162- client,
163- spaceId,
164- sourceLocalId : nodeId ,
165- fname : attachment . path ,
166- mimetype,
167- created : new Date ( attachment . stat . ctime ) ,
168- lastModified : new Date ( attachment . stat . mtime ) ,
169- content,
170- } ) ;
181+ const existingRef = existingReferencesByPath [ attachment . path ] ;
182+ if (
183+ ! existingRef ||
184+ new Date ( existingRef . last_modified + "Z" ) . valueOf ( ) <
185+ attachment . stat . mtime
186+ ) {
187+ const content = await plugin . app . vault . readBinary ( attachment ) ;
188+ await addFile ( {
189+ client,
190+ spaceId,
191+ sourceLocalId : nodeId ,
192+ fname : attachment . path ,
193+ mimetype,
194+ created : new Date ( attachment . stat . ctime ) ,
195+ lastModified : new Date ( attachment . stat . mtime ) ,
196+ content,
197+ } ) ;
198+ }
171199 }
172200 let cleanupCommand = client
173201 . from ( "FileReference" )
@@ -182,7 +210,7 @@ export const publishNode = async ({
182210 // do not fail on cleanup
183211 if ( cleanupResult . error ) console . error ( cleanupResult . error ) ;
184212
185- if ( ! existingPublish . includes ( myGroup ) )
213+ if ( commonGroups . length === 0 )
186214 await plugin . app . fileManager . processFrontMatter (
187215 file ,
188216 ( fm : Record < string , unknown > ) => {
0 commit comments