Skip to content

JavaScript: Create the document foreground

createDocumentForeground(target) from kizunasync/supabase builds an IForeground over a document-shaped object.

The createSupabaseKizunaSync call in src/kizunasync.ts, shown on Initializing, builds one over document by itself when neither its foreground option nor the driver supplies a port. The browser driver supplies none, so nothing in a standard browser app calls this factory. Read this page to watch a different document, such as an iframe's own, or to see which page events count as a return to the foreground.

Examples#

Basic#

// src/kizunasync.ts (excerpt)
import { createDocumentForeground } from 'kizunasync/supabase'

const foreground = createDocumentForeground(document)

Pass it to the client#

To watch an iframe, pass its contentDocument in place of document.

// src/kizunasync.ts
import { byOwner, defineConfig } from 'kizunasync'
import { createDocumentForeground, createSupabaseKizunaSync } from 'kizunasync/supabase'
import { createWebWorkerDriver } from 'kizunasync/web'
import { supabase } from './supabase-client'

const config = defineConfig({
  tables: { todos: { sync: 'read-write', bucket: byOwner('user_id') } },
})

export const kizunasync = createSupabaseKizunaSync({
  supabase,
  driver: createWebWorkerDriver('todos.db'),
  config,
  foreground: createDocumentForeground(document),
})

An explicit foreground wins over the driver's port and over the default. Unlike the default, which checks for document first, this module reads document as it loads, so it does not suit a module a static render imports.

Parameters#

NameTypeRequiredDescription
targetIForegroundDocumentYesA document-shaped object: visibilityState, addEventListener, removeEventListener, and an optional defaultView for pageshow. Narrow enough that a test fake can implement it with no DOM lib types.

Returns#

IForeground, the value Initializing takes as its foreground argument.

NameTypeRequiredDescription
subscribe(onForeground: () => void) => () => void—Fires on a visibilitychange to 'visible', on the target's own resume event, and on a pageshow whose persisted is true. Returns the function that removes all three listeners.

Errors#

This factory throws nothing.

Notes#

visibilitychange alone misses two returns to life that the Page Lifecycle API defines. A frozen tab runs no timers and no fetch callbacks, and it gets a resume event when the browser unfreezes it. A page restored from the back/forward cache gets pageshow with persisted: true, and it never re-fires visibilitychange. The port observes resume on the target itself. It observes pageshow on target.defaultView when that exists, and on the target otherwise.

createSupabaseKizunaSync composes this port with refreshOnForeground and the reconnect nudge Initializing describes. On Expo and React Native, the Expo driver carries createExpoForeground() on device, so the composition uses that port and builds no document port.

Found a problem? Edit this page on GitHub