web_lib

Common web application libraries
git clone https://radroots.dev/git/web_lib.git
Log | Files | Refs | LICENSE

commit 9ebce20c5565dd1c1c657a14226dff460541abd1
parent cbb512e3c48682400f9e16539b1d1701dd630bfa
Author: triesap <triesap@radroots.dev>
Date:   Sun, 28 Dec 2025 15:03:06 +0000

farm: upgrade events payloads and geo tooling

- Align event-facing types and client surfaces for new farm/geo data model
- Expand WebTangleDatabase client API for plots, gcs locations, tags, members, and event state
- Update farms add form/types/schema to use about/website/location label and optional geopoint/geocode
- Fix lat/lng formatting order, add GeoJSON point/circle helpers, and introduce uuidv7 b64url d-tags

Diffstat:
Mapps-lib-pwa/package.json | 2+-
Mapps-lib-pwa/src/lib/components/farm/farms-add-detail.svelte | 44+++++++++++++++++++++-----------------------
Mapps-lib-pwa/src/lib/types/app.ts | 4++--
Mapps-lib-pwa/src/lib/types/views/farms.ts | 12++++++------
Mapps-lib-pwa/src/lib/types/views/profile.ts | 2+-
Mapps-lib-pwa/src/lib/utils/farm/schema.ts | 15+++++++--------
Mapps-lib-pwa/src/lib/views/farms/farms-add.svelte | 33++++++++++++++-------------------
Mclient/package.json | 4++--
Mclient/src/tangle/types.ts | 156+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-----------
Mclient/src/tangle/web.ts | 444++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---------
Mgeo/package.json | 2+-
Mgeo/src/format.ts | 4++--
Mgeo/src/gcs.ts | 4++--
Ageo/src/geojson.ts | 57+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgeo/src/index.ts | 1+
Mgeo/src/types.ts | 4++--
Mlocales/src/messages/en/error.json | 2+-
Mutils/src/id/index.ts | 29++++++++++++++++++++++++++++-
18 files changed, 678 insertions(+), 141 deletions(-)

diff --git a/apps-lib-pwa/package.json b/apps-lib-pwa/package.json @@ -82,7 +82,7 @@ "@radroots/events-bindings": "workspace:*", "@radroots/client": "workspace:*", "@radroots/geo": "workspace:*", - "@radroots/tangle-schema-bindings": "workspace:*", + "@radroots/tangle-db-schema-bindings": "workspace:*", "@radroots/themes": "workspace:*", "@radroots/utils": "workspace:*", "@sveltekit-i18n/base": "^1.3.7", diff --git a/apps-lib-pwa/src/lib/components/farm/farms-add-detail.svelte b/apps-lib-pwa/src/lib/components/farm/farms-add-detail.svelte @@ -2,24 +2,21 @@ import FormLineLedger from "$lib/components/form/form-line-ledger.svelte"; import type { LibContext } from "$lib/types/context"; import { get_context } from "@radroots/apps-lib"; - import { area_units, form_fields } from "@radroots/utils"; const { ls } = get_context<LibContext>(`lib`); let { val_farmname = $bindable(``), val_farmaddress = $bindable(``), - val_farmarea = $bindable(``), - val_farmarea_unit = $bindable(``), - val_farmcontact = $bindable(``), + val_farmabout = $bindable(``), + val_farmwebsite = $bindable(``), farm_geop_lat, farm_geop_lng, }: { val_farmname: string; val_farmaddress: string; - val_farmarea: string; - val_farmarea_unit: string; - val_farmcontact: string; + val_farmabout: string; + val_farmwebsite: string; farm_geop_lat: string; farm_geop_lng: string; } = $props(); @@ -74,25 +71,26 @@ }} /> <FormLineLedger - bind:value={val_farmarea} - bind:value_label_sel={val_farmarea_unit} + bind:value={val_farmabout} basis={{ - id: `farm_size`, - label: `${$ls(`common.farm_size`)}`, - label_select: { - label: `${$ls(`units.area.${val_farmarea_unit}_ab`)}`, - entries: area_units.map((i) => ({ - value: i, - label: `${$ls(`units.area.${i}`)}`, - })), - }, + id: `farm_about`, + label: `${$ls(`common.about`)}`, input: { placeholder: `${`${$ls(`icu.enter_*`, { - value: `${$ls(`common.farm_size`)}`.toLowerCase(), - })}`} ${`${$ls( - `units.area.${val_farmarea_unit}_pl`, - )}`.toLowerCase()}`, - field: form_fields.farm_size, + value: `${$ls(`common.about`)}`.toLowerCase(), + })}`}`, + }, + }} + /> + <FormLineLedger + bind:value={val_farmwebsite} + basis={{ + id: `farm_website`, + label: `${$ls(`common.website`)}`, + input: { + placeholder: `${$ls(`icu.enter_*`, { + value: `${$ls(`common.website`)}`.toLowerCase(), + })}`, }, }} /> diff --git a/apps-lib-pwa/src/lib/types/app.ts b/apps-lib-pwa/src/lib/types/app.ts @@ -1,7 +1,7 @@ import type { TangleDatabaseBackup } from "@radroots/client/tangle"; import type { IdbClientConfig } from "@radroots/utils"; -export type AppConfigRole = `farmer` | `personal` +export type AppConfigRole = `farmer` | `individual` export type AppLayoutKeyIOS = `ios0` | `ios1`; export type AppLayoutKeyWeb = `webm0` | `webm1`; @@ -32,7 +32,7 @@ export type LabelFieldKind = `link` | `on` | `shade`; export type BackupVersions = { app: string; - tangle_sql: string; + tangle_db: string; backup_format: string; }; diff --git a/apps-lib-pwa/src/lib/types/views/farms.ts b/apps-lib-pwa/src/lib/types/views/farms.ts @@ -1,4 +1,4 @@ -import type { Farm } from "@radroots/tangle-schema-bindings"; +import type { Farm } from "@radroots/tangle-db-schema-bindings"; import type { GeocoderReverseResult, GeolocationPoint, LocationBasis } from "@radroots/geo"; export type FarmExtended = { @@ -18,11 +18,11 @@ export type IViewFarmsData = { export type IViewFarmsAddSubmission = { farm_name: string; - farm_area?: number; - farm_area_unit?: string; - farm_contact_name?: string; - geolocation_point: GeolocationPoint; - geocode_result: GeocoderReverseResult; + farm_about?: string; + farm_website?: string; + farm_location_label?: string; + geolocation_point?: GeolocationPoint; + geocode_result?: GeocoderReverseResult; }; export type IViewFarmsProductsAddSubmitPayload = { diff --git a/apps-lib-pwa/src/lib/types/views/profile.ts b/apps-lib-pwa/src/lib/types/views/profile.ts @@ -1,4 +1,4 @@ -import type { NostrProfile } from "@radroots/tangle-schema-bindings"; +import type { NostrProfile } from "@radroots/tangle-db-schema-bindings"; export type IViewProfileData = { profile: NostrProfile; diff --git a/apps-lib-pwa/src/lib/utils/farm/schema.ts b/apps-lib-pwa/src/lib/utils/farm/schema.ts @@ -1,17 +1,17 @@ import { dev } from "$app/environment"; import type { IViewFarmsAddSubmission, IViewFarmsProductsAddSubmitPayload } from "$lib/types/views/farms"; import { schema_geocode_result, schema_geolocation_point } from "@radroots/geo"; -import { form_fields, util_rxp, zf_numf_pos, zf_numi_pos, zf_price } from "@radroots/utils"; +import { form_fields, util_rxp, zf_numi_pos, zf_price } from "@radroots/utils"; import { z } from "zod"; export const schema_view_farms_add_submission: z.ZodSchema<IViewFarmsAddSubmission> = z.object({ farm_name: z.string().regex(form_fields.farm_name.validate), - farm_area: zf_numf_pos.optional(), - farm_area_unit: z.string().regex(form_fields.area_unit.validate).optional(), - farm_contact_name: z.string().regex(form_fields.contact_name.validate).optional(), - geolocation_point: schema_geolocation_point, - geocode_result: schema_geocode_result, + farm_about: z.string().optional(), + farm_website: z.string().optional(), + farm_location_label: z.string().optional(), + geolocation_point: schema_geolocation_point.optional(), + geocode_result: schema_geocode_result.optional(), }); export const schema_view_farms_products_add_submission: z.ZodSchema<IViewFarmsProductsAddSubmitPayload> = z.object({ @@ -27,4 +27,4 @@ export const schema_view_farms_products_add_submission: z.ZodSchema<IViewFarmsPr quantity_label: z.string().regex(form_fields.quantity_label.validate), geolocation_point: schema_geolocation_point, geocode_result: schema_geocode_result, -}); -\ No newline at end of file +}); diff --git a/apps-lib-pwa/src/lib/views/farms/farms-add.svelte b/apps-lib-pwa/src/lib/views/farms/farms-add.svelte @@ -31,7 +31,7 @@ type GeolocationAddress, type GeolocationPoint, } from "@radroots/geo"; - import { parse_float, type CallbackPromiseGeneric } from "@radroots/utils"; + import { type CallbackPromiseGeneric } from "@radroots/utils"; const { ls, locale, lc_gui_alert, lc_geop_current, lc_geocode } = get_context<LibContext>(`lib`); @@ -52,9 +52,8 @@ let val_farmname = $state(``); let val_farmaddress = $state(``); - let val_farmcontact = $state(``); - let val_farmarea = $state(``); - let val_farmarea_unit = $state(`ac`); + let val_farmabout = $state(``); + let val_farmwebsite = $state(``); const carousel_farms_add = carousel_create({ view: "farms_add", @@ -97,21 +96,18 @@ }; const handle_continue_1 = async (): Promise<void> => { - if (!map_geop || !map_geoc) - return void lc_gui_alert(`No farm location provided.`); // @todo + const geolocation_point = geop_is_valid(map_geop) + ? map_geop + : undefined; + const geocode_result = map_geoc; const farms_add_submission = schema_view_farms_add_submission.safeParse( { farm_name: val_farmname, - farm_area: val_farmarea ? parse_float(val_farmarea) : undefined, - farm_area_unit: - val_farmarea && val_farmarea_unit - ? val_farmarea_unit - : undefined, - farm_contact_name: val_farmcontact - ? val_farmcontact - : undefined, - geolocation_point: map_geop, - geocode_result: map_geoc, + farm_about: val_farmabout ? val_farmabout : undefined, + farm_website: val_farmwebsite ? val_farmwebsite : undefined, + farm_location_label: val_farmaddress ? val_farmaddress : undefined, + geolocation_point, + geocode_result, } satisfies IViewFarmsAddSubmission, ); @@ -209,9 +205,8 @@ <FarmsAddDetails bind:val_farmname bind:val_farmaddress - bind:val_farmcontact - bind:val_farmarea - bind:val_farmarea_unit + bind:val_farmabout + bind:val_farmwebsite {farm_geop_lat} {farm_geop_lng} /> diff --git a/client/package.json b/client/package.json @@ -88,8 +88,8 @@ "dependencies": { "@radroots/geo": "workspace:*", "@radroots/http": "workspace:*", - "@radroots/tangle-schema-bindings": "workspace:*", - "@radroots/tangle-sql-wasm": "workspace:*", + "@radroots/tangle-db-schema-bindings": "workspace:*", + "@radroots/tangle-db-wasm": "workspace:*", "@radroots/types-bindings": "workspace:*", "@radroots/utils": "workspace:*", "@radroots/nostr": "workspace:*", diff --git a/client/src/tangle/types.ts b/client/src/tangle/types.ts @@ -9,16 +9,56 @@ import type { IFarmFindOneResolve, IFarmUpdate, IFarmUpdateResolve, - ILocationGcsCreate, - ILocationGcsCreateResolve, - ILocationGcsDelete, - ILocationGcsDeleteResolve, - ILocationGcsFindMany, - ILocationGcsFindManyResolve, - ILocationGcsFindOne, - ILocationGcsFindOneResolve, - ILocationGcsUpdate, - ILocationGcsUpdateResolve, + IFarmGcsLocationCreate, + IFarmGcsLocationCreateResolve, + IFarmGcsLocationDelete, + IFarmGcsLocationDeleteResolve, + IFarmGcsLocationFindMany, + IFarmGcsLocationFindManyResolve, + IFarmGcsLocationFindOne, + IFarmGcsLocationFindOneResolve, + IFarmGcsLocationUpdate, + IFarmGcsLocationUpdateResolve, + IFarmMemberClaimCreate, + IFarmMemberClaimCreateResolve, + IFarmMemberClaimDelete, + IFarmMemberClaimDeleteResolve, + IFarmMemberClaimFindMany, + IFarmMemberClaimFindManyResolve, + IFarmMemberClaimFindOne, + IFarmMemberClaimFindOneResolve, + IFarmMemberClaimUpdate, + IFarmMemberClaimUpdateResolve, + IFarmMemberCreate, + IFarmMemberCreateResolve, + IFarmMemberDelete, + IFarmMemberDeleteResolve, + IFarmMemberFindMany, + IFarmMemberFindManyResolve, + IFarmMemberFindOne, + IFarmMemberFindOneResolve, + IFarmMemberUpdate, + IFarmMemberUpdateResolve, + IFarmTagCreate, + IFarmTagCreateResolve, + IFarmTagDelete, + IFarmTagDeleteResolve, + IFarmTagFindMany, + IFarmTagFindManyResolve, + IFarmTagFindOne, + IFarmTagFindOneResolve, + IFarmTagUpdate, + IFarmTagUpdateResolve, + IGcsLocationCreate, + IGcsLocationCreateResolve, + IGcsLocationDelete, + IGcsLocationDeleteResolve, + IGcsLocationFindMany, + IGcsLocationFindManyResolve, + IGcsLocationFindOne, + IGcsLocationFindOneResolve, + IGcsLocationUpdate, + IGcsLocationUpdateResolve, ILogErrorCreate, ILogErrorCreateResolve, ILogErrorDelete, @@ -39,6 +79,16 @@ import type { IMediaImageFindOneResolve, IMediaImageUpdate, IMediaImageUpdateResolve, + INostrEventStateCreate, + INostrEventStateCreateResolve, + INostrEventStateDelete, + INostrEventStateDeleteResolve, + INostrEventStateFindMany, + INostrEventStateFindManyResolve, + INostrEventStateFindOne, + INostrEventStateFindOneResolve, + INostrEventStateUpdate, + INostrEventStateUpdateResolve, INostrProfileCreate, INostrProfileCreateResolve, INostrProfileDelete, @@ -59,6 +109,36 @@ import type { INostrRelayFindOneResolve, INostrRelayUpdate, INostrRelayUpdateResolve, + IPlotCreate, + IPlotCreateResolve, + IPlotDelete, + IPlotDeleteResolve, + IPlotFindMany, + IPlotFindManyResolve, + IPlotFindOne, + IPlotFindOneResolve, + IPlotGcsLocationCreate, + IPlotGcsLocationCreateResolve, + IPlotGcsLocationDelete, + IPlotGcsLocationDeleteResolve, + IPlotGcsLocationFindMany, + IPlotGcsLocationFindManyResolve, + IPlotGcsLocationFindOne, + IPlotGcsLocationFindOneResolve, + IPlotGcsLocationUpdate, + IPlotGcsLocationUpdateResolve, + IPlotTagCreate, + IPlotTagCreateResolve, + IPlotTagDelete, + IPlotTagDeleteResolve, + IPlotTagFindMany, + IPlotTagFindManyResolve, + IPlotTagFindOne, + IPlotTagFindOneResolve, + IPlotTagUpdate, + IPlotTagUpdateResolve, + IPlotUpdate, + IPlotUpdateResolve, ITradeProductCreate, ITradeProductCreateResolve, ITradeProductDelete, @@ -69,15 +149,13 @@ import type { ITradeProductFindOneResolve, ITradeProductUpdate, ITradeProductUpdateResolve, - IFarmLocationRelation, - IFarmLocationResolve, INostrProfileRelayRelation, INostrProfileRelayResolve, ITradeProductLocationRelation, ITradeProductLocationResolve, ITradeProductMediaRelation, ITradeProductMediaResolve -} from "@radroots/tangle-schema-bindings"; +} from "@radroots/tangle-db-schema-bindings"; import { type SqlJsMigrationState } from "../sql/types.js"; import type { IError } from "@radroots/types-bindings"; import type { TangleDatabaseBackup } from "./web.js"; @@ -96,11 +174,51 @@ export interface IClientTangleDatabase { farm_find_many(opts?: IFarmFindMany): Promise<IFarmFindManyResolve | IError<string>>; farm_delete(opts: IFarmDelete): Promise<IFarmDeleteResolve | IError<string>>; farm_update(opts: IFarmUpdate): Promise<IFarmUpdateResolve | IError<string>>; - location_gcs_create(opts: ILocationGcsCreate): Promise<ILocationGcsCreateResolve | IError<string>>; - location_gcs_find_one(opts: ILocationGcsFindOne): Promise<ILocationGcsFindOneResolve | IError<string>>; - location_gcs_find_many(opts?: ILocationGcsFindMany): Promise<ILocationGcsFindManyResolve | IError<string>>; - location_gcs_delete(opts: ILocationGcsDelete): Promise<ILocationGcsDeleteResolve | IError<string>>; - location_gcs_update(opts: ILocationGcsUpdate): Promise<ILocationGcsUpdateResolve | IError<string>>; + plot_create(opts: IPlotCreate): Promise<IPlotCreateResolve | IError<string>>; + plot_find_one(opts: IPlotFindOne): Promise<IPlotFindOneResolve | IError<string>>; + plot_find_many(opts?: IPlotFindMany): Promise<IPlotFindManyResolve | IError<string>>; + plot_delete(opts: IPlotDelete): Promise<IPlotDeleteResolve | IError<string>>; + plot_update(opts: IPlotUpdate): Promise<IPlotUpdateResolve | IError<string>>; + gcs_location_create(opts: IGcsLocationCreate): Promise<IGcsLocationCreateResolve | IError<string>>; + gcs_location_find_one(opts: IGcsLocationFindOne): Promise<IGcsLocationFindOneResolve | IError<string>>; + gcs_location_find_many(opts?: IGcsLocationFindMany): Promise<IGcsLocationFindManyResolve | IError<string>>; + gcs_location_delete(opts: IGcsLocationDelete): Promise<IGcsLocationDeleteResolve | IError<string>>; + gcs_location_update(opts: IGcsLocationUpdate): Promise<IGcsLocationUpdateResolve | IError<string>>; + farm_gcs_location_create(opts: IFarmGcsLocationCreate): Promise<IFarmGcsLocationCreateResolve | IError<string>>; + farm_gcs_location_find_one(opts: IFarmGcsLocationFindOne): Promise<IFarmGcsLocationFindOneResolve | IError<string>>; + farm_gcs_location_find_many(opts?: IFarmGcsLocationFindMany): Promise<IFarmGcsLocationFindManyResolve | IError<string>>; + farm_gcs_location_delete(opts: IFarmGcsLocationDelete): Promise<IFarmGcsLocationDeleteResolve | IError<string>>; + farm_gcs_location_update(opts: IFarmGcsLocationUpdate): Promise<IFarmGcsLocationUpdateResolve | IError<string>>; + plot_gcs_location_create(opts: IPlotGcsLocationCreate): Promise<IPlotGcsLocationCreateResolve | IError<string>>; + plot_gcs_location_find_one(opts: IPlotGcsLocationFindOne): Promise<IPlotGcsLocationFindOneResolve | IError<string>>; + plot_gcs_location_find_many(opts?: IPlotGcsLocationFindMany): Promise<IPlotGcsLocationFindManyResolve | IError<string>>; + plot_gcs_location_delete(opts: IPlotGcsLocationDelete): Promise<IPlotGcsLocationDeleteResolve | IError<string>>; + plot_gcs_location_update(opts: IPlotGcsLocationUpdate): Promise<IPlotGcsLocationUpdateResolve | IError<string>>; + farm_tag_create(opts: IFarmTagCreate): Promise<IFarmTagCreateResolve | IError<string>>; + farm_tag_find_one(opts: IFarmTagFindOne): Promise<IFarmTagFindOneResolve | IError<string>>; + farm_tag_find_many(opts?: IFarmTagFindMany): Promise<IFarmTagFindManyResolve | IError<string>>; + farm_tag_delete(opts: IFarmTagDelete): Promise<IFarmTagDeleteResolve | IError<string>>; + farm_tag_update(opts: IFarmTagUpdate): Promise<IFarmTagUpdateResolve | IError<string>>; + plot_tag_create(opts: IPlotTagCreate): Promise<IPlotTagCreateResolve | IError<string>>; + plot_tag_find_one(opts: IPlotTagFindOne): Promise<IPlotTagFindOneResolve | IError<string>>; + plot_tag_find_many(opts?: IPlotTagFindMany): Promise<IPlotTagFindManyResolve | IError<string>>; + plot_tag_delete(opts: IPlotTagDelete): Promise<IPlotTagDeleteResolve | IError<string>>; + plot_tag_update(opts: IPlotTagUpdate): Promise<IPlotTagUpdateResolve | IError<string>>; + farm_member_create(opts: IFarmMemberCreate): Promise<IFarmMemberCreateResolve | IError<string>>; + farm_member_find_one(opts: IFarmMemberFindOne): Promise<IFarmMemberFindOneResolve | IError<string>>; + farm_member_find_many(opts?: IFarmMemberFindMany): Promise<IFarmMemberFindManyResolve | IError<string>>; + farm_member_delete(opts: IFarmMemberDelete): Promise<IFarmMemberDeleteResolve | IError<string>>; + farm_member_update(opts: IFarmMemberUpdate): Promise<IFarmMemberUpdateResolve | IError<string>>; + farm_member_claim_create(opts: IFarmMemberClaimCreate): Promise<IFarmMemberClaimCreateResolve | IError<string>>; + farm_member_claim_find_one(opts: IFarmMemberClaimFindOne): Promise<IFarmMemberClaimFindOneResolve | IError<string>>; + farm_member_claim_find_many(opts?: IFarmMemberClaimFindMany): Promise<IFarmMemberClaimFindManyResolve | IError<string>>; + farm_member_claim_delete(opts: IFarmMemberClaimDelete): Promise<IFarmMemberClaimDeleteResolve | IError<string>>; + farm_member_claim_update(opts: IFarmMemberClaimUpdate): Promise<IFarmMemberClaimUpdateResolve | IError<string>>; + nostr_event_state_create(opts: INostrEventStateCreate): Promise<INostrEventStateCreateResolve | IError<string>>; + nostr_event_state_find_one(opts: INostrEventStateFindOne): Promise<INostrEventStateFindOneResolve | IError<string>>; + nostr_event_state_find_many(opts?: INostrEventStateFindMany): Promise<INostrEventStateFindManyResolve | IError<string>>; + nostr_event_state_delete(opts: INostrEventStateDelete): Promise<INostrEventStateDeleteResolve | IError<string>>; + nostr_event_state_update(opts: INostrEventStateUpdate): Promise<INostrEventStateUpdateResolve | IError<string>>; log_error_create(opts: ILogErrorCreate): Promise<ILogErrorCreateResolve | IError<string>>; log_error_find_one(opts: ILogErrorFindOne): Promise<ILogErrorFindOneResolve | IError<string>>; log_error_find_many(opts?: ILogErrorFindMany): Promise<ILogErrorFindManyResolve | IError<string>>; @@ -126,8 +244,6 @@ export interface IClientTangleDatabase { trade_product_find_many(opts?: ITradeProductFindMany): Promise<ITradeProductFindManyResolve | IError<string>>; trade_product_delete(opts: ITradeProductDelete): Promise<ITradeProductDeleteResolve | IError<string>>; trade_product_update(opts: ITradeProductUpdate): Promise<ITradeProductUpdateResolve | IError<string>>; - farm_location_set(opts: IFarmLocationRelation): Promise<IFarmLocationResolve | IError<string>>; - farm_location_unset(opts: IFarmLocationRelation): Promise<IFarmLocationResolve | IError<string>>; nostr_profile_relay_set(opts: INostrProfileRelayRelation): Promise<INostrProfileRelayResolve | IError<string>>; nostr_profile_relay_unset(opts: INostrProfileRelayRelation): Promise<INostrProfileRelayResolve | IError<string>>; trade_product_location_set(opts: ITradeProductLocationRelation): Promise<ITradeProductLocationResolve | IError<string>>; diff --git a/client/src/tangle/web.ts b/client/src/tangle/web.ts @@ -9,16 +9,56 @@ import type { IFarmFindOneResolve, IFarmUpdate, IFarmUpdateResolve, - ILocationGcsCreate, - ILocationGcsCreateResolve, - ILocationGcsDelete, - ILocationGcsDeleteResolve, - ILocationGcsFindMany, - ILocationGcsFindManyResolve, - ILocationGcsFindOne, - ILocationGcsFindOneResolve, - ILocationGcsUpdate, - ILocationGcsUpdateResolve, + IFarmGcsLocationCreate, + IFarmGcsLocationCreateResolve, + IFarmGcsLocationDelete, + IFarmGcsLocationDeleteResolve, + IFarmGcsLocationFindMany, + IFarmGcsLocationFindManyResolve, + IFarmGcsLocationFindOne, + IFarmGcsLocationFindOneResolve, + IFarmGcsLocationUpdate, + IFarmGcsLocationUpdateResolve, + IFarmMemberClaimCreate, + IFarmMemberClaimCreateResolve, + IFarmMemberClaimDelete, + IFarmMemberClaimDeleteResolve, + IFarmMemberClaimFindMany, + IFarmMemberClaimFindManyResolve, + IFarmMemberClaimFindOne, + IFarmMemberClaimFindOneResolve, + IFarmMemberClaimUpdate, + IFarmMemberClaimUpdateResolve, + IFarmMemberCreate, + IFarmMemberCreateResolve, + IFarmMemberDelete, + IFarmMemberDeleteResolve, + IFarmMemberFindMany, + IFarmMemberFindManyResolve, + IFarmMemberFindOne, + IFarmMemberFindOneResolve, + IFarmMemberUpdate, + IFarmMemberUpdateResolve, + IFarmTagCreate, + IFarmTagCreateResolve, + IFarmTagDelete, + IFarmTagDeleteResolve, + IFarmTagFindMany, + IFarmTagFindManyResolve, + IFarmTagFindOne, + IFarmTagFindOneResolve, + IFarmTagUpdate, + IFarmTagUpdateResolve, + IGcsLocationCreate, + IGcsLocationCreateResolve, + IGcsLocationDelete, + IGcsLocationDeleteResolve, + IGcsLocationFindMany, + IGcsLocationFindManyResolve, + IGcsLocationFindOne, + IGcsLocationFindOneResolve, + IGcsLocationUpdate, + IGcsLocationUpdateResolve, ILogErrorCreate, ILogErrorCreateResolve, ILogErrorDelete, @@ -39,6 +79,16 @@ import type { IMediaImageFindOneResolve, IMediaImageUpdate, IMediaImageUpdateResolve, + INostrEventStateCreate, + INostrEventStateCreateResolve, + INostrEventStateDelete, + INostrEventStateDeleteResolve, + INostrEventStateFindMany, + INostrEventStateFindManyResolve, + INostrEventStateFindOne, + INostrEventStateFindOneResolve, + INostrEventStateUpdate, + INostrEventStateUpdateResolve, INostrProfileCreate, INostrProfileCreateResolve, INostrProfileDelete, @@ -59,6 +109,36 @@ import type { INostrRelayFindOneResolve, INostrRelayUpdate, INostrRelayUpdateResolve, + IPlotCreate, + IPlotCreateResolve, + IPlotDelete, + IPlotDeleteResolve, + IPlotFindMany, + IPlotFindManyResolve, + IPlotFindOne, + IPlotFindOneResolve, + IPlotGcsLocationCreate, + IPlotGcsLocationCreateResolve, + IPlotGcsLocationDelete, + IPlotGcsLocationDeleteResolve, + IPlotGcsLocationFindMany, + IPlotGcsLocationFindManyResolve, + IPlotGcsLocationFindOne, + IPlotGcsLocationFindOneResolve, + IPlotGcsLocationUpdate, + IPlotGcsLocationUpdateResolve, + IPlotTagCreate, + IPlotTagCreateResolve, + IPlotTagDelete, + IPlotTagDeleteResolve, + IPlotTagFindMany, + IPlotTagFindManyResolve, + IPlotTagFindOne, + IPlotTagFindOneResolve, + IPlotTagUpdate, + IPlotTagUpdateResolve, + IPlotUpdate, + IPlotUpdateResolve, ITradeProductCreate, ITradeProductCreateResolve, ITradeProductDelete, @@ -69,15 +149,13 @@ import type { ITradeProductFindOneResolve, ITradeProductUpdate, ITradeProductUpdateResolve, - IFarmLocationRelation, - IFarmLocationResolve, INostrProfileRelayRelation, INostrProfileRelayResolve, ITradeProductLocationRelation, ITradeProductLocationResolve, ITradeProductMediaRelation, ITradeProductMediaResolve -} from "@radroots/tangle-schema-bindings"; +} from "@radroots/tangle-db-schema-bindings"; import init_wasm, { query_sql, tangle_db_farm_create, @@ -85,11 +163,46 @@ import init_wasm, { tangle_db_farm_find_many, tangle_db_farm_find_one, tangle_db_farm_update, - tangle_db_location_gcs_create, - tangle_db_location_gcs_delete, - tangle_db_location_gcs_find_many, - tangle_db_location_gcs_find_one, - tangle_db_location_gcs_update, + tangle_db_plot_create, + tangle_db_plot_delete, + tangle_db_plot_find_many, + tangle_db_plot_find_one, + tangle_db_plot_update, + tangle_db_gcs_location_create, + tangle_db_gcs_location_delete, + tangle_db_gcs_location_find_many, + tangle_db_gcs_location_find_one, + tangle_db_gcs_location_update, + tangle_db_farm_gcs_location_create, + tangle_db_farm_gcs_location_delete, + tangle_db_farm_gcs_location_find_many, + tangle_db_farm_gcs_location_find_one, + tangle_db_farm_gcs_location_update, + tangle_db_plot_gcs_location_create, + tangle_db_plot_gcs_location_delete, + tangle_db_plot_gcs_location_find_many, + tangle_db_plot_gcs_location_find_one, + tangle_db_plot_gcs_location_update, + tangle_db_farm_tag_create, + tangle_db_farm_tag_delete, + tangle_db_farm_tag_find_many, + tangle_db_farm_tag_find_one, + tangle_db_farm_tag_update, + tangle_db_plot_tag_create, + tangle_db_plot_tag_delete, + tangle_db_plot_tag_find_many, + tangle_db_plot_tag_find_one, + tangle_db_plot_tag_update, + tangle_db_farm_member_create, + tangle_db_farm_member_delete, + tangle_db_farm_member_find_many, + tangle_db_farm_member_find_one, + tangle_db_farm_member_update, + tangle_db_farm_member_claim_create, + tangle_db_farm_member_claim_delete, + tangle_db_farm_member_claim_find_many, + tangle_db_farm_member_claim_find_one, + tangle_db_farm_member_claim_update, tangle_db_log_error_create, tangle_db_log_error_delete, tangle_db_log_error_find_many, @@ -100,6 +213,11 @@ import init_wasm, { tangle_db_media_image_find_many, tangle_db_media_image_find_one, tangle_db_media_image_update, + tangle_db_nostr_event_state_create, + tangle_db_nostr_event_state_delete, + tangle_db_nostr_event_state_find_many, + tangle_db_nostr_event_state_find_one, + tangle_db_nostr_event_state_update, tangle_db_nostr_profile_create, tangle_db_nostr_profile_delete, tangle_db_nostr_profile_find_many, @@ -115,8 +233,6 @@ import init_wasm, { tangle_db_trade_product_find_many, tangle_db_trade_product_find_one, tangle_db_trade_product_update, - tangle_db_farm_location_set, - tangle_db_farm_location_unset, tangle_db_nostr_profile_relay_set, tangle_db_nostr_profile_relay_unset, tangle_db_trade_product_location_set, @@ -127,7 +243,7 @@ import init_wasm, { tangle_db_run_migrations, tangle_db_export_backup, tangle_db_import_backup -} from "@radroots/tangle-sql-wasm"; +} from "@radroots/tangle-db-wasm"; import type { IError } from "@radroots/types-bindings"; import { err_msg, handle_err, type IdbClientConfig } from "@radroots/utils"; import { IDB_CONFIG_TANGLE } from "../idb/config.js"; @@ -139,7 +255,7 @@ import type { IWebTangleDatabase } from "./types.js"; export type TangleDatabaseBackup = { format_version: string; - tangle_sql_version: string; + tangle_db_version: string; schema: { object_type: string; name: string; @@ -205,7 +321,7 @@ const is_backup_migration_entry = (value: unknown): value is TangleDatabaseBacku const is_tangle_database_backup = (value: unknown): value is TangleDatabaseBackup => { if (!is_record(value)) return false; if (typeof value.format_version !== "string") return false; - if (typeof value.tangle_sql_version !== "string") return false; + if (typeof value.tangle_db_version !== "string") return false; if (!Array.isArray(value.schema) || !value.schema.every(is_backup_schema_entry)) return false; if (!Array.isArray(value.data) || !value.data.every(is_backup_data_entry)) return false; if (!Array.isArray(value.migrations) || !value.migrations.every(is_backup_migration_entry)) return false; @@ -411,34 +527,244 @@ export class WebTangleDatabase implements IWebTangleDatabase { return this.deserialize<IFarmUpdateResolve>(res); } - async location_gcs_create(opts: ILocationGcsCreate): Promise<ILocationGcsCreateResolve | IError<string>> { + async plot_create(opts: IPlotCreate): Promise<IPlotCreateResolve | IError<string>> { await this.ensure_ready(); - const res = await tangle_db_location_gcs_create(this.serialize(opts)); - return this.deserialize<ILocationGcsCreateResolve>(res); + const res = await tangle_db_plot_create(this.serialize(opts)); + return this.deserialize<IPlotCreateResolve>(res); } - async location_gcs_find_one(opts: ILocationGcsFindOne): Promise<ILocationGcsFindOneResolve | IError<string>> { + async plot_find_one(opts: IPlotFindOne): Promise<IPlotFindOneResolve | IError<string>> { await this.ensure_ready(); - const res = await tangle_db_location_gcs_find_one(this.serialize(opts)); - return this.deserialize<ILocationGcsFindOneResolve>(res); + const res = await tangle_db_plot_find_one(this.serialize(opts)); + return this.deserialize<IPlotFindOneResolve>(res); } - async location_gcs_find_many(opts?: ILocationGcsFindMany): Promise<ILocationGcsFindManyResolve | IError<string>> { + async plot_find_many(opts?: IPlotFindMany): Promise<IPlotFindManyResolve | IError<string>> { await this.ensure_ready(); - const res = await tangle_db_location_gcs_find_many(this.serialize(opts ?? {})); - return this.deserialize<ILocationGcsFindManyResolve>(res); + const res = await tangle_db_plot_find_many(this.serialize(opts ?? {})); + return this.deserialize<IPlotFindManyResolve>(res); } - async location_gcs_delete(opts: ILocationGcsDelete): Promise<ILocationGcsDeleteResolve | IError<string>> { + async plot_delete(opts: IPlotDelete): Promise<IPlotDeleteResolve | IError<string>> { await this.ensure_ready(); - const res = await tangle_db_location_gcs_delete(this.serialize(opts)); - return this.deserialize<ILocationGcsDeleteResolve>(res); + const res = await tangle_db_plot_delete(this.serialize(opts)); + return this.deserialize<IPlotDeleteResolve>(res); } - async location_gcs_update(opts: ILocationGcsUpdate): Promise<ILocationGcsUpdateResolve | IError<string>> { + async plot_update(opts: IPlotUpdate): Promise<IPlotUpdateResolve | IError<string>> { await this.ensure_ready(); - const res = await tangle_db_location_gcs_update(this.serialize(opts)); - return this.deserialize<ILocationGcsUpdateResolve>(res); + const res = await tangle_db_plot_update(this.serialize(opts)); + return this.deserialize<IPlotUpdateResolve>(res); + } + + async gcs_location_create(opts: IGcsLocationCreate): Promise<IGcsLocationCreateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_gcs_location_create(this.serialize(opts)); + return this.deserialize<IGcsLocationCreateResolve>(res); + } + + async gcs_location_find_one(opts: IGcsLocationFindOne): Promise<IGcsLocationFindOneResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_gcs_location_find_one(this.serialize(opts)); + return this.deserialize<IGcsLocationFindOneResolve>(res); + } + + async gcs_location_find_many(opts?: IGcsLocationFindMany): Promise<IGcsLocationFindManyResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_gcs_location_find_many(this.serialize(opts ?? {})); + return this.deserialize<IGcsLocationFindManyResolve>(res); + } + + async gcs_location_delete(opts: IGcsLocationDelete): Promise<IGcsLocationDeleteResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_gcs_location_delete(this.serialize(opts)); + return this.deserialize<IGcsLocationDeleteResolve>(res); + } + + async gcs_location_update(opts: IGcsLocationUpdate): Promise<IGcsLocationUpdateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_gcs_location_update(this.serialize(opts)); + return this.deserialize<IGcsLocationUpdateResolve>(res); + } + + async farm_gcs_location_create(opts: IFarmGcsLocationCreate): Promise<IFarmGcsLocationCreateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_gcs_location_create(this.serialize(opts)); + return this.deserialize<IFarmGcsLocationCreateResolve>(res); + } + + async farm_gcs_location_find_one(opts: IFarmGcsLocationFindOne): Promise<IFarmGcsLocationFindOneResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_gcs_location_find_one(this.serialize(opts)); + return this.deserialize<IFarmGcsLocationFindOneResolve>(res); + } + + async farm_gcs_location_find_many(opts?: IFarmGcsLocationFindMany): Promise<IFarmGcsLocationFindManyResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_gcs_location_find_many(this.serialize(opts ?? {})); + return this.deserialize<IFarmGcsLocationFindManyResolve>(res); + } + + async farm_gcs_location_delete(opts: IFarmGcsLocationDelete): Promise<IFarmGcsLocationDeleteResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_gcs_location_delete(this.serialize(opts)); + return this.deserialize<IFarmGcsLocationDeleteResolve>(res); + } + + async farm_gcs_location_update(opts: IFarmGcsLocationUpdate): Promise<IFarmGcsLocationUpdateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_gcs_location_update(this.serialize(opts)); + return this.deserialize<IFarmGcsLocationUpdateResolve>(res); + } + + async plot_gcs_location_create(opts: IPlotGcsLocationCreate): Promise<IPlotGcsLocationCreateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_gcs_location_create(this.serialize(opts)); + return this.deserialize<IPlotGcsLocationCreateResolve>(res); + } + + async plot_gcs_location_find_one(opts: IPlotGcsLocationFindOne): Promise<IPlotGcsLocationFindOneResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_gcs_location_find_one(this.serialize(opts)); + return this.deserialize<IPlotGcsLocationFindOneResolve>(res); + } + + async plot_gcs_location_find_many(opts?: IPlotGcsLocationFindMany): Promise<IPlotGcsLocationFindManyResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_gcs_location_find_many(this.serialize(opts ?? {})); + return this.deserialize<IPlotGcsLocationFindManyResolve>(res); + } + + async plot_gcs_location_delete(opts: IPlotGcsLocationDelete): Promise<IPlotGcsLocationDeleteResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_gcs_location_delete(this.serialize(opts)); + return this.deserialize<IPlotGcsLocationDeleteResolve>(res); + } + + async plot_gcs_location_update(opts: IPlotGcsLocationUpdate): Promise<IPlotGcsLocationUpdateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_gcs_location_update(this.serialize(opts)); + return this.deserialize<IPlotGcsLocationUpdateResolve>(res); + } + + async farm_tag_create(opts: IFarmTagCreate): Promise<IFarmTagCreateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_tag_create(this.serialize(opts)); + return this.deserialize<IFarmTagCreateResolve>(res); + } + + async farm_tag_find_one(opts: IFarmTagFindOne): Promise<IFarmTagFindOneResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_tag_find_one(this.serialize(opts)); + return this.deserialize<IFarmTagFindOneResolve>(res); + } + + async farm_tag_find_many(opts?: IFarmTagFindMany): Promise<IFarmTagFindManyResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_tag_find_many(this.serialize(opts ?? {})); + return this.deserialize<IFarmTagFindManyResolve>(res); + } + + async farm_tag_delete(opts: IFarmTagDelete): Promise<IFarmTagDeleteResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_tag_delete(this.serialize(opts)); + return this.deserialize<IFarmTagDeleteResolve>(res); + } + + async farm_tag_update(opts: IFarmTagUpdate): Promise<IFarmTagUpdateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_tag_update(this.serialize(opts)); + return this.deserialize<IFarmTagUpdateResolve>(res); + } + + async plot_tag_create(opts: IPlotTagCreate): Promise<IPlotTagCreateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_tag_create(this.serialize(opts)); + return this.deserialize<IPlotTagCreateResolve>(res); + } + + async plot_tag_find_one(opts: IPlotTagFindOne): Promise<IPlotTagFindOneResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_tag_find_one(this.serialize(opts)); + return this.deserialize<IPlotTagFindOneResolve>(res); + } + + async plot_tag_find_many(opts?: IPlotTagFindMany): Promise<IPlotTagFindManyResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_tag_find_many(this.serialize(opts ?? {})); + return this.deserialize<IPlotTagFindManyResolve>(res); + } + + async plot_tag_delete(opts: IPlotTagDelete): Promise<IPlotTagDeleteResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_tag_delete(this.serialize(opts)); + return this.deserialize<IPlotTagDeleteResolve>(res); + } + + async plot_tag_update(opts: IPlotTagUpdate): Promise<IPlotTagUpdateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_plot_tag_update(this.serialize(opts)); + return this.deserialize<IPlotTagUpdateResolve>(res); + } + + async farm_member_create(opts: IFarmMemberCreate): Promise<IFarmMemberCreateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_create(this.serialize(opts)); + return this.deserialize<IFarmMemberCreateResolve>(res); + } + + async farm_member_find_one(opts: IFarmMemberFindOne): Promise<IFarmMemberFindOneResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_find_one(this.serialize(opts)); + return this.deserialize<IFarmMemberFindOneResolve>(res); + } + + async farm_member_find_many(opts?: IFarmMemberFindMany): Promise<IFarmMemberFindManyResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_find_many(this.serialize(opts ?? {})); + return this.deserialize<IFarmMemberFindManyResolve>(res); + } + + async farm_member_delete(opts: IFarmMemberDelete): Promise<IFarmMemberDeleteResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_delete(this.serialize(opts)); + return this.deserialize<IFarmMemberDeleteResolve>(res); + } + + async farm_member_update(opts: IFarmMemberUpdate): Promise<IFarmMemberUpdateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_update(this.serialize(opts)); + return this.deserialize<IFarmMemberUpdateResolve>(res); + } + + async farm_member_claim_create(opts: IFarmMemberClaimCreate): Promise<IFarmMemberClaimCreateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_claim_create(this.serialize(opts)); + return this.deserialize<IFarmMemberClaimCreateResolve>(res); + } + + async farm_member_claim_find_one(opts: IFarmMemberClaimFindOne): Promise<IFarmMemberClaimFindOneResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_claim_find_one(this.serialize(opts)); + return this.deserialize<IFarmMemberClaimFindOneResolve>(res); + } + + async farm_member_claim_find_many(opts?: IFarmMemberClaimFindMany): Promise<IFarmMemberClaimFindManyResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_claim_find_many(this.serialize(opts ?? {})); + return this.deserialize<IFarmMemberClaimFindManyResolve>(res); + } + + async farm_member_claim_delete(opts: IFarmMemberClaimDelete): Promise<IFarmMemberClaimDeleteResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_claim_delete(this.serialize(opts)); + return this.deserialize<IFarmMemberClaimDeleteResolve>(res); + } + + async farm_member_claim_update(opts: IFarmMemberClaimUpdate): Promise<IFarmMemberClaimUpdateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_farm_member_claim_update(this.serialize(opts)); + return this.deserialize<IFarmMemberClaimUpdateResolve>(res); } async log_error_create(opts: ILogErrorCreate): Promise<ILogErrorCreateResolve | IError<string>> { @@ -531,6 +857,36 @@ export class WebTangleDatabase implements IWebTangleDatabase { return this.deserialize<INostrProfileUpdateResolve>(res); } + async nostr_event_state_create(opts: INostrEventStateCreate): Promise<INostrEventStateCreateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_nostr_event_state_create(this.serialize(opts)); + return this.deserialize<INostrEventStateCreateResolve>(res); + } + + async nostr_event_state_find_one(opts: INostrEventStateFindOne): Promise<INostrEventStateFindOneResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_nostr_event_state_find_one(this.serialize(opts)); + return this.deserialize<INostrEventStateFindOneResolve>(res); + } + + async nostr_event_state_find_many(opts?: INostrEventStateFindMany): Promise<INostrEventStateFindManyResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_nostr_event_state_find_many(this.serialize(opts ?? {})); + return this.deserialize<INostrEventStateFindManyResolve>(res); + } + + async nostr_event_state_delete(opts: INostrEventStateDelete): Promise<INostrEventStateDeleteResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_nostr_event_state_delete(this.serialize(opts)); + return this.deserialize<INostrEventStateDeleteResolve>(res); + } + + async nostr_event_state_update(opts: INostrEventStateUpdate): Promise<INostrEventStateUpdateResolve | IError<string>> { + await this.ensure_ready(); + const res = await tangle_db_nostr_event_state_update(this.serialize(opts)); + return this.deserialize<INostrEventStateUpdateResolve>(res); + } + async nostr_relay_create(opts: INostrRelayCreate): Promise<INostrRelayCreateResolve | IError<string>> { await this.ensure_ready(); const res = await tangle_db_nostr_relay_create(this.serialize(opts)); @@ -591,18 +947,6 @@ export class WebTangleDatabase implements IWebTangleDatabase { return this.deserialize<ITradeProductUpdateResolve>(res); } - async farm_location_set(opts: IFarmLocationRelation): Promise<IFarmLocationResolve | IError<string>> { - await this.ensure_ready(); - const res = await tangle_db_farm_location_set(this.serialize(opts)); - return this.deserialize<IFarmLocationResolve>(res); - } - - async farm_location_unset(opts: IFarmLocationRelation): Promise<IFarmLocationResolve | IError<string>> { - await this.ensure_ready(); - const res = await tangle_db_farm_location_unset(this.serialize(opts)); - return this.deserialize<IFarmLocationResolve>(res); - } - async nostr_profile_relay_set(opts: INostrProfileRelayRelation): Promise<INostrProfileRelayResolve | IError<string>> { await this.ensure_ready(); const res = await tangle_db_nostr_profile_relay_set(this.serialize(opts)); diff --git a/geo/package.json b/geo/package.json @@ -35,7 +35,7 @@ }, "dependencies": { "@radroots/utils": "workspace:*", - "@radroots/tangle-schema-bindings": "workspace:*", + "@radroots/tangle-db-schema-bindings": "workspace:*", "geohashing": "^2.0.1", "zod": "^4.0.5" } diff --git a/geo/src/format.ts b/geo/src/format.ts @@ -19,8 +19,8 @@ export const fmt_geometry_point_coords = ( point: GeometryPoint, locale: string ): string => { - const lat = geol_lat_fmt(point.coordinates[0], "dms", locale, 3); - const lng = geol_lng_fmt(point.coordinates[1], "dms", locale, 3); + const lat = geol_lat_fmt(point.coordinates[1], "dms", locale, 3); + const lng = geol_lng_fmt(point.coordinates[0], "dms", locale, 3); return `${lat}, ${lng}`; }; diff --git a/geo/src/gcs.ts b/geo/src/gcs.ts @@ -1,4 +1,4 @@ -import type { LocationGcs } from "@radroots/tangle-schema-bindings"; +import type { GcsLocation } from "@radroots/tangle-db-schema-bindings"; import type { LocationBasis } from "./types.js"; export const gcs_to_location_basis = ({ @@ -8,7 +8,7 @@ export const gcs_to_location_basis = ({ gc_name: primary, gc_admin1_name: admin, gc_country_id: country, -}: LocationGcs): LocationBasis => ({ +}: GcsLocation): LocationBasis => ({ id, point: { lat, diff --git a/geo/src/geojson.ts b/geo/src/geojson.ts @@ -0,0 +1,57 @@ +import type { GeolocationPoint, GeometryPoint, GeometryPolygon } from "./types.js"; + +const WGS84_RADIUS_M = 6378137; +const DEFAULT_CIRCLE_STEPS = 64; +const COORD_SCALE = 1_000_000; + +const rad_from_deg = (deg: number): number => (deg * Math.PI) / 180; +const deg_from_rad = (rad: number): number => (rad * 180) / Math.PI; +const wrap_lng = (lng: number): number => ((lng + 540) % 360) - 180; +const round_coord = (value: number): number => Math.round(value * COORD_SCALE) / COORD_SCALE; + +export const geojson_point_from_geopoint = (geol_p: GeolocationPoint): GeometryPoint => ({ + type: "Point", + coordinates: [geol_p.lng, geol_p.lat], +}); + +export const geojson_polygon_circle_wgs84 = (opts: { + geol_p: GeolocationPoint; + radius_m?: number; + steps?: number; +}): GeometryPolygon => { + const { geol_p } = opts; + const radius_m_raw = opts.radius_m; + const radius_m = typeof radius_m_raw === "number" && Number.isFinite(radius_m_raw) && radius_m_raw > 0 + ? radius_m_raw + : 100; + const steps_raw = opts.steps; + const steps_val = typeof steps_raw === "number" && Number.isFinite(steps_raw) && steps_raw > 0 + ? Math.round(steps_raw) + : DEFAULT_CIRCLE_STEPS; + const step_count = Math.max(4, steps_val); + const lat_rad = rad_from_deg(geol_p.lat); + const lng_rad = rad_from_deg(geol_p.lng); + const angular_distance = radius_m / WGS84_RADIUS_M; + const sin_lat = Math.sin(lat_rad); + const cos_lat = Math.cos(lat_rad); + const sin_ad = Math.sin(angular_distance); + const cos_ad = Math.cos(angular_distance); + const coords: Array<[number, number]> = []; + for (let i = 0; i <= step_count; i++) { + const bearing = (i * 2 * Math.PI) / step_count; + const lat_rad_next = Math.asin( + sin_lat * cos_ad + cos_lat * sin_ad * Math.cos(bearing), + ); + const lng_rad_next = lng_rad + Math.atan2( + Math.sin(bearing) * sin_ad * cos_lat, + cos_ad - sin_lat * Math.sin(lat_rad_next), + ); + const lat_next = round_coord(deg_from_rad(lat_rad_next)); + const lng_next = round_coord(wrap_lng(deg_from_rad(lng_rad_next))); + coords.push([lng_next, lat_next]); + } + return { + type: "Polygon", + coordinates: [coords], + }; +}; diff --git a/geo/src/index.ts b/geo/src/index.ts @@ -1,6 +1,7 @@ export * from "./bounds.js"; export * from "./format.js"; export * from "./gcs.js"; +export * from "./geojson.js"; export * from "./geohash.js"; export * from "./parse.js"; export * from "./schema.js"; diff --git a/geo/src/types.ts b/geo/src/types.ts @@ -1,11 +1,11 @@ export type GeometryPoint = { type: string; - coordinates: number[]; + coordinates: [number, number]; }; export type GeometryPolygon = { type: string; - coordinates: number[][][]; + coordinates: Array<Array<[number, number]>>; }; export type GeolocationPointTuple = [number, number]; diff --git a/locales/src/messages/en/error.json b/locales/src/messages/en/error.json @@ -72,7 +72,7 @@ "missing_version_metadata": "Import file is missing version metadata.", "no_file_chosen": "Choose a backup file before continuing.", "storage_mismatch": "Import failed: {{label}} storage mismatch (app={{app_database}}/{{app_store}}, backup={{backup_database}}/{{backup_store}}).", - "tangle_sql_version_mismatch": "Import file tangle-sql version does not match metadata.", + "tangle_db_version_mismatch": "Import file tangle-db version does not match metadata.", "tangle_store_key_mismatch": "Import failed: tangle DB store key mismatch (app={{app_store_key}}, backup={{backup_store_key}}).", "unsupported_backup_version": "Unsupported backup version ({{backup_version}}); expected {{expected_version}}." }, diff --git a/utils/src/id/index.ts b/utils/src/id/index.ts @@ -1,3 +1,30 @@ -import { v4 } from "uuid"; +import { parse, v4, v7 } from "uuid"; export const uuidv4 = () => v4(); +export const uuidv7 = () => v7(); + +const bytes_to_b64 = (bytes: Uint8Array): string => { + if (typeof btoa === "undefined") throw new Error("btoa_undefined"); + const chars: string[] = new Array(bytes.length); + for (let i = 0; i < bytes.length; i++) chars[i] = String.fromCharCode(bytes[i]); + return btoa(chars.join("")); +}; + +const b64_to_b64url = (value: string): string => + value.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, ""); + +export const uuidv4_b64url = (): string => { + const uuid_val = uuidv4(); + const bytes = parse(uuid_val); + const b64 = bytes_to_b64(bytes); + return b64_to_b64url(b64); +}; + +export const uuidv7_b64url = (): string => { + const uuid_val = uuidv7(); + const bytes = parse(uuid_val); + const b64 = bytes_to_b64(bytes); + return b64_to_b64url(b64); +}; + +export const d_tag_create = (): string => uuidv7_b64url();