# 🚧 wip.

I am working towards creating the fundamental es module package structure before
pulling out behavior from the [ionic-gib](https://github.com/wraiford/ibgib/tree/v0.2.729/ionic-gib) project into this lib. so this is just a
shell right now.

# forward

I have created a working MVP for ibgib that shows some of the potential for the
architecture:

* try it out
  * https://ibgib.space
* pre-refactored MVP codebase on GitHub
  * `ionic-gib`: https://github.com/wraiford/ibgib/tree/v0.2.729/ionic-gib
  * "pre-refactored" = doesn't use this core-gib lib, but rather is the
    springboard/"carcass" for it.
* base ibgib protocol graphing substrate lib on GitLab
  * `ts-gib`: https://gitlab.com/ibgib/ts-gib/-/tree/master

# Development & Cross-Platform Support

We are migrating this codebase to be fully cross-platform (Windows, Linux, macOS).
Previously, some npm scripts relied on bash-specific commands like `rm -rf`.
These have been replaced with custom Node.js scripts located in the `tools/` directory.

## Tools

### `tools/clean.js`
Recursively removes directories. Replacement for `rm -rf`.
Usage: `node tools/clean.js <path1> <path2> ...`
Example (in `package.json`): `"clean": "node tools/clean.js ./dist"`

### `tools/ensure-dirs.js`
Recursively creates directories (idempotent). Replacement for `mkdir -p`.
Usage: `node tools/ensure-dirs.js <path1> <path2> ...`
Example: `node tools/ensure-dirs.js ./dist/logs`

## Migration Guide (for other ibgib libs)
To repeat this setup in other libraries:
1. Copy the `tools/` directory to the library root.
2. Update `package.json` scripts:
   - Replace `rm -rf <path>` with `node tools/clean.js <path>`
   - Replace `mkdir -p <path>` with `node tools/ensure-dirs.js <path>`
3. Ensure `package.json` has `"type": "module"` (or convert scripts to CommonJS if needed).

# core-gib

`core-gib` is the intermediate ibgib substrate that provides functionality for basic ibgib interactions.

This includes plumbing for the following primary areas:

* witnesses
* spaces
* apps
* robbots

_note: many of these could technically be its own library, but at the very least for now these will stay within this core library until it seems they should be broken out._

This sits on top of the lowest level `ts-gib` library, which provides the very basic
primitives used in the mechanics of ibgib graphing.

## witnesses

### witness pseudocode at 10,000 feet

```
interface Witness extends IbGib {
  function witness(ibgib) => ibgib
}

let resultIbgib = await myIbgib.witness(argIbGib)
```

So, a witness is a specific type of ibgib that _does_ something. It exposes
itself to other ibgibs via a single function that takes in a single ibgib and
returns a single ibgib. Since ibgibs are content-addressable, this makes it
similar to a universally-addressed function that accepts a single
universally-addressed argument and returns a single universally-addressed result
in a universally-sized computer.

It is called a "witness" and not, say, a "function", "object", or "universal
function/object", etc., because "witness" conveys that instead of being an
impartial function, **the ibgib has a POV**. This associates an identity at the
most fundamental level, giving flesh to the bias that exists in the function.
This also abstracts away implementation details of individual functional
implementations, be they in different languages, different architectures, etc.

So in short, a witness is a distributed computation metaversal function, but
personified in order to remind each of us of anything's fallibility (including
computer functions).

### witness in real code

With this in mind, let's look at the witness interface definitions in
TypeScript, with generic types and comments removed for clarity.

```typescript
export interface IbGib {
    ib: Ib;    // string
    gib?: Gib; // string
}

export interface IbGibWithDataAndRel8ns<...> extends IbGib {
    data?: TData;     // object/map of string->any
    rel8ns?: TRel8ns; // map of string->string[]
}

export interface Witness<...> extends IbGibWithDataAndRel8ns<...> {
    witness(arg: TIbGibIn): Promise<TIbGibOut | undefined>;
}
```

This last `Witness` interface has a single member: the `witness` function. This
accepts a single ibgib arg and returns a single ibgib result. Since each ibgib
is content addressed[^1], this allows for a function addressing scheme that
effectively works in an infinite addressing space.

Considering this, the ibgib + witness design can be thought of as a superset of
all programming languages with `witness` ibgib acting similar to how we think of
functions. So inter-witness communications are at the extreme of functional
programming. Or said another way it can describe any programming language. But
when it comes to execution, adding the isomorphic transformation into the ibgib
description space would necessarily add overhead and most likely create
unfeasible execution times (until computation power vastly improves relative to
our current POV in time). Or in short, it would be NECESSARILY SLOWER, to the
point of local impracticality.

Still, it's important to think each witness as a universally addressed function,
and each space as a special case witness whose job is colocation.

[^1] primitives and other ibgibs without a gib hash, like "6^gib" or "hello^gib", are still "content addressed", it's simply the value is the address itself.

## spaces

So a "witness" is an ibgib with behavior, i.e. doesn't just have data. A "space"
is one kind of witness. Its primary job is to collocate ibgib according to some definition of location.

_nuance: The implementation of "collocation" is not concrete and can be decided by - and vary wildly by - the implementing class._

### types of spaces

Ideally all spaces are to be considered equally, with the idea being that you
treat them as buckets of data. As such, we can think of them like a bucket or a
very basic [repository](https://deviq.com/design-patterns/repository-pattern) with just a couple capabilities: `get`, `put`, etc.

But when dealing with the process of living, temporal data dynamics, we must
consider one key aspect of data: **perspective**, i.e. POV. As such, there are
necessarily(?) three "types" of space with respect to POV:

1. local space
2. outer space
3. inner space

These are currently implemented in the ionic-gib MVP as follows:

1. local space
  * implemented with [`IonicSpace_V1`](https://github.com/wraiford/ibgib/blob/ed2d09c411dfdbc916e7841f1a0ccb6b559c303a/ionic-gib/src/app/common/witnesses/spaces/ionic-space-v1.ts)
  * uses [capacitor filesystem api (v4)](https://capacitorjs.com/docs/apis/filesystem)
    as indexeddb substrate
2. outer space
  * implemented with [`AWSDynamoSpace_V1`](https://github.com/wraiford/ibgib/blob/ed2d09c411dfdbc916e7841f1a0ccb6b559c303a/ionic-gib/src/app/common/witnesses/spaces/aws-dynamo-space-v1.ts#L854)
  * this is implemented as a "merge" space, in that when ibgibs are "put" into
    the space, timelines are dynamically merged using a CRDT-like merging
    algorithm that applies unapplied DNA transforms
  * uses DynamoDB for most ibgib data stored as four string fields ([max string size of 400 KB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/ServiceQuotas.html))
  * uses S3 for larger ibgibs with DynamoDB entries that indicate S3 storage
3. inner space
  * the [InnerSpace_V1](https://github.com/wraiford/ibgib/blob/ed2d09c411dfdbc916e7841f1a0ccb6b559c303a/ionic-gib/src/app/common/witnesses/spaces/inner-space-v1.ts) is not used or tested
  * it is only sketched
  * better composeability will be required for inner spaces to be utilized

## witnesses, and thus spaces, as universally addressed functions

If you think of a function in a programming language, it has a couple of characteristics:

* has an address
* has at least one parameter, which ultimately has an an address (either in the stack/heap or a pointer to memory)
* returns 0-1+ data structures


## spaces related to witnesses

## bootstrap



## testing

### importmaps - `npm run test:browser` fails

not implemented with respec-gib yet but this is what has to happen for import
map. as a workaround for bleeding edge ES module consumption (let alone testing
frameworks for them), to include an import map section. So atow paste the
following code before any other `script` tags in the `head` section.  (the
versions may need to change):

_note: if you are having CORS issues, it may be due to the cdn being down._

using **unpkg**:

```html
  <script type="importmap">
    {
      "imports": {
        "@ibgib/helper-gib": "https://unpkg.com/@ibgib/helper-gib@0.0.4/dist/index.mjs",
        "@ibgib/helper-gib/": "https://unpkg.com/@ibgib/helper-gib@0.0.4/",
        "@ibgib/ts-gib": "https://unpkg.com/@ibgib/ts-gib@0.5.1/dist/index.mjs",
        "@ibgib/ts-gib/": "https://unpkg.com/@ibgib/ts-gib@0.5.1/",
        "@ibgib/encrypt-gib": "https://unpkg.com/@ibgib/encrypt-gib@0.1.6/dist/index.mjs",
        "@ibgib/encrypt-gib/": "https://unpkg.com/@ibgib/encrypt-gib@0.1.6/"
      }
    }
  </script>
```

**using jsdelivr.net**:

```html
  <script type="importmap">
    {
      "imports": {
        "@ibgib/helper-gib": "https://cdn.jsdelivr.net/npm/@ibgib/helper-gib@0.0.4/dist/index.mjs",
        "@ibgib/helper-gib/": "https://cdn.jsdelivr.net/npm/@ibgib/helper-gib@0.0.4/",
        "@ibgib/ts-gib": "https://cdn.jsdelivr.net/npm/@ibgib/ts-gib@0.5.1/dist/index.mjs",
        "@ibgib/ts-gib/": "https://cdn.jsdelivr.net/npm/@ibgib/ts-gib@0.5.1/",
        "@ibgib/encrypt-gib": "https://cdn.jsdelivr.net/npm/@ibgib/encrypt-gib@0.1.6/dist/index.mjs",
        "@ibgib/encrypt-gib/": "https://cdn.jsdelivr.net/npm/@ibgib/encrypt-gib@0.1.6/"
      }
    }
  </script>
```

# carcass related

## find and replace patterns

### remove constants scoping

import \* as c from .+

### scoped ts-gib for helper first

(import .+')ts-gib(.*helper)';
$1@ibgib/ts-gib$2.mjs';

### scoped ts-gib for non-helper next

(import .+')ts-gib(.*)';
$1@ibgib/ts-gib$2';

### non-mjs suffixed imports

(from '.+[\w\/]\w\w\w)'
$1.mjs'

### add index.mjs explicit to folder imports

(from '.+/V1)'
$1/index.mjs'

### convert cast to use `as` operator

(<)(\w+)(>)([\w.!\?]+)(\W)
($4 as $2)$5
