# @momsfriendlydevco/supabase-reactive

> Supabase plugin for reactive read/write against local objects

Latest version **1.1.0** (published 2024-11-10) · MIT license · 0 weekly downloads

## Install

```sh
npm install @momsfriendlydevco/supabase-reactive
pnpm add @momsfriendlydevco/supabase-reactive
yarn add @momsfriendlydevco/supabase-reactive
bun add @momsfriendlydevco/supabase-reactive
```

## Health

**Score 30/100 (F)** — status: maintenance-mode.

Positive: esm support; no vulnerabilities.

Warnings: low downloads; no types.

Negative: stale; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.1.0 |
| Published | 2024-11-10 |
| First published | 2023-11-16 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM |
| Node | >=18.17.1 |
| Dependencies | 5 |
| Unpacked size | 34.8 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Matt Carter |
| Maintainers | hash-bang, 1watt, eekthecat, melromero, mr-yellow |
| Keywords | supabase, reactive |

## Links

- npm: https://www.npmjs.com/package/@momsfriendlydevco/supabase-reactive
- Repository: https://github.com/MomsFriendlyDevCo/supabase-reactive
- Homepage: https://github.com/MomsFriendlyDevCo/supabase-reactive#readme
- Issues: https://github.com/MomsFriendlyDevCo/supabase-reactive/issues
- npm.io page: https://npm.io/package/@momsfriendlydevco/supabase-reactive

## Dependencies (5)

- [vue](https://npm.io/package/vue.md) ^3.5.12
- [eslint](https://npm.io/package/eslint.md) ^9.13.0
- [lodash-es](https://npm.io/package/lodash-es.md) ^4.17.21
- [@supabase/supabase-js](https://npm.io/package/@supabase/supabase-js.md) ^2.45.6
- [@momsfriendlydevco/eslint-config](https://npm.io/package/@momsfriendlydevco/eslint-config.md) ^2.0.5

## Recent versions

- 1.1.0 (latest) — 2024-11-10
- 1.0.12 — 2024-10-24
- 1.0.11 — 2024-05-23
- 1.0.10 — 2024-05-07
- 1.0.9 — 2024-04-26
- 1.0.8 — 2024-04-18
- 1.0.7 — 2024-02-21
- 1.0.6 — 2024-02-17
- 1.0.4 — 2023-12-13
- 1.0.3 — 2023-11-23
- 1.0.2 — 2023-11-16
- 1.0.1 — 2023-11-16

## README

@MomsFriendlyDevCo/Supabase-Reactive
====================================
Supabase plugin for reactive read/write against local objects.

Extends the existing [Supabase](https://supabase.com) JavaScript functionality by adding a bi-directional, bound object which syncs with the server when its state changes. Changes on the server (or from another client) similarly update local state across all clients.

```javascript
import Reactive from '@momsfriendlydevco/supabase-reactive';
import {createClient} from '@supabase/supabase-js'

// Create a Supabase client
let supabase = creatClient('https://MY-SUPABASE-DOMAIN.supabase.co', 'big-long-key');

// Create a reactive
let state = Reactive('my-table/id-to-sync', {supabase});

// Changes to state are now synced bi-directionally
state.foo = 1;
state.bar = [1, 2, 3];
state.baz = {key1: {subkey1: [4, 5, 6]}};
delete state.bar;
```


API
===

Supabase Table Structure
------------------------
Ideally the data structure within Supabase should be made up of these columns:

* `id` - a UUID is recommended
* `created_at` - optional timestamp to indicate when the row was created
* `edited_at` - timestamp to track changes
* `version` - optional numeric to indicate the version offset of the row
* `data` - the main JSONB data entity storage

An example Postgres data command is:

```sql
create table
  public.test (
    id uuid not null default gen_random_uuid (),
    created_at timestamp with time zone not null default now(),
    edited_at timestamp with time zone null,
    data jsonb null,
    version bigint null,
    constraint test_pkey primary key (id),
    constraint test_id_key unique (id)
  ) tablespace pg_default;
```


SupabaseReactive(path, options)
------------------------------
The main exported function which returns a Reactive object.

The resulting reactive object also has a series of non-enumerable utility functions which all start with a single dollar sign. See below for their purpose and documentation.

This can take an optional shorthand path and/or an options structure.

Valid options are:

| Option            | Type                   | Default       | Description                                                                                                                                     |
|-------------------|------------------------|---------------|-------------------------------------------------------------------------------------------------------------------------------------------------|
| `supbase`         | `Supabase`             |               | Supabase instance to use                                                                                                                        |
| `table`           | `String`               |               | Supabase table to store data within if `path` is not specified                                                                                  |
| `id`              | `String`               |               | ID of the table row to sync data with                                                                                                           |
| `isArray`         | `Boolean`              | `false`       | Specifies if the data entity is an Array rather than an object                                                                                  |
| `read=true`       | `Boolean`              | `true`        | Allow reading from the remote Supabase server, disabling this makes the data transfer transmit only                                             |
| `watch=true`      | `Boolean`              | `true`        | Allow watching for local changes and write them to the remote server if enabled                                                                 |
| `write=true`      | `Boolean`              | `true`        | Allow writing back local changes to the Supabase server                                                                                         |
| `attachReactives` | `Boolean`              | `true`        | Expose all utility functions as '$' prefixed functions to control the local state                                                               |
| `throttle`        | `Object`               |               | Lodash debounce options + `wait` key used to throttle all writes, set to falsy to disable                                                       |
| `idColumn='id'`   | `String`               | `'id'`        | Row ID column to sync with                                                                                                                      |
| `filter`          | `Object`               |               | Query filter to use when accessing multiple rows                                                                                                |
| `dataColumn`      | `String`               | `'data'`      | Data / JSONB column to sync data with                                                                                                           |
| `timestampColumn` | `String`               | `'edited_at'` | Timezone+TZ column to use when syncing data                                                                                                     |
| `versionColumn`   | `String`               |               | Optional version column, this increments on each write and is only really useful for debugging purposes                                         |
| `reactiveCreate`  | `Function`             |               | Async function used to create an observable / reactive data entity from its input. Defaults to Vue's reactive function                          |
| `reactiveWatch`   | `Function`             |               | Async function used to create a watch on the created reactive. Defaults to Vue's watch function                                                 |
| `onInit`          | `Function`             |               | Async function when first populating data from the remote. Called as `(data)`                                                                   |
| `onRead`          | `Function`             |               | Async function called on subsequent reads when populating data from the remote. Called as `(data)`                                              |
| `onChange`        | `Function`             |               | Async function called when a detected local write is about to be sent to the remote. Called as `(dataPayload)`                                  |
| `onDestroy`       | `Function`             |               | Async function called when destroying state. Called as `(data:Reactive)`                                                                        |
| `debug`           | `Function` / `Boolean` |               | Optional debugging function callback. Called as `(...msg:Any)`                                                                                  |
| `splitPath`       | `Function`             |               | Path parser, expected to decorate the `settings` object. Called as `(path: String, settings: Object)` and expected to mutate the settings state |


defaults
--------
Storage object for all defaults used by `SupabaseReactive`.


Reactive.$meta
--------------
Meta information about the current row.
This only really exists because we can't assign scalars in Javascript without it resetting the pointer later.

This object is made up of:

| Key         | Type              | Description                                                                                                   |
|-------------|-------------------|---------------------------------------------------------------------------------------------------------------|
| `id`        | `String`          | The ID of the current row                                                                                     |
| `table`     | `String`          | The active table for the current row                                                                          |
| `timestamp` | `Null` / `Date`   | The last known timestamp of data from the server (or NULL if no data has been pulled yet)                     |
| `If`        | `Null` / `Number` | a versioning column is enabled this represents the last known version of the data, similar to $meta.timestamp |
| `Whether`   | `Boolean`         | the state is being updated locally - indicates that local watchers should ignore incoming change detection    |


Reactive.$set(state, options)
-----------------------------
Sets the content of the current reactive.

Valid options are:

| Option         | Type      | Default | Description                                                                        |
|----------------|-----------|---------|------------------------------------------------------------------------------------|
| `markUpdating` | `Boolean` | `true`  | Mark the object as within an update to prevent recursion + disable local observers |
| `removeKeys`   | `Boolean` | `true`  | Clean out dead reactive keys if the new state doesn't also contain them            |
| `timestamp`    | `Date`    |         | Set the reactive timestamp if provided                                             |
| `version`      | `Number`  |         | Set the reactive version if provided                                               |


Reactive.$toObject()
--------------------
Tidy JSON field data so that is safe from private methods (anything starting with '$' or '_', proxies or other non POJO slush.
Returns a POJO.


Reactive.$refresh()
-------------------
Alias of `Reactive.$read()`.


Reactive.$getQuery()
--------------------
Generate a Supabase object representing a query for the current configuration.
Returns a Supabase promise which resolves when the operation has completed


Reactive.$init()
----------------
Initial operaton to wait on data from service + return reactable
This function is the default response when calling the outer `SupabaseReactive()` function.


Reactive.$read()
----------------
Fetch the current data state from the server and update the reactive.
Returns a promise.


Reactive.$fetch()
-----------------
Fetch the current data state from the server but don't update the local state.
This function is only really useful for snapshotting server state.
Returns a promise which resolves with the snapshot data.


Reactive.$watch(isWatching=true)
--------------------------------
Watch local data for changes and push to the server as needed.
Returns a promise.


Reactive.$flush()
-----------------
Wait for all local writes to complete.
NOTE: This only promises that local writes complete, not that a subsequent read is required.
Returns a promise.


Reactive.$subscribe(isSubscribed=true)
--------------------------------------
Toggle subscription to the realtime datafeed.
Returns a promise.


Reactive.$destroy()
-------------------
Release all watchers and subscriptions, local and remote.
Returns a promise.

---
_Source: https://npm.io/package/@momsfriendlydevco/supabase-reactive · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
