@carbonorm/carbonreact 3.6.2 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -28,6 +28,7 @@ export { default as CarbonWebSocket } from "./components/WebSocket/CarbonWebSock
28
28
  export * from "./components/WebSocket/CarbonWebSocket";
29
29
  export * from "./hoc/GlobalHistory";
30
30
  export * from "./hoc/KeysMatching";
31
+ export * from "./hoc/SubsetMatching";
31
32
  export { default as addValidSQL } from "./hoc/addValidSQL";
32
33
  export * from "./hoc/addValidSQL";
33
34
  export { default as changed } from "./hoc/changed";
package/dist/index.esm.js CHANGED
@@ -1,4 +1,4 @@
1
- import react, { useRef, useState, useEffect, Component, createContext, useContext, lazy } from 'react';
1
+ import react, { useRef, useState, useEffect, Component, createContext, lazy } from 'react';
2
2
  import { toastOptions, clearCache, timeout, axiosInstance, isVerbose, checkAllRequestsComplete } from '@carbonorm/carbonnode';
3
3
  import { useNavigate } from 'react-router-dom';
4
4
  import { toast, ToastContainer } from 'react-toastify';
@@ -1409,11 +1409,11 @@ function hexToRgb (hex) {
1409
1409
 
1410
1410
  var styles = {"maintenance-hero":"C5KSPNF","maintenanceHero":"C5KSPNF","httpStatusCode":"NhyRQts","centeredContainer":"nA4Uno6","errorTextGeneral":"yJAgaUs","errorKeys":"SRIoY4m","error-values":"xQIsoNw","errorValues":"xQIsoNw","error-pre":"C6eWpJ3","errorPre":"C6eWpJ3","line-number":"NFRyo7M","lineNumber":"NFRyo7M","cl":"vR2jbfr","slide":"OO2C-Wp"};
1411
1411
 
1412
- var BackendThrowable = () => {
1413
- const bootstrap = CarbonReact.instance;
1414
- const currentThrowable = bootstrap.state.backendThrowable[0];
1415
- console.log([bootstrap.state.backendThrowable, currentThrowable]);
1416
- return jsxRuntime_2("div", { className: styles.maintenanceHero, children: [jsxRuntime_1("h1", { className: styles.httpStatusCode, children: currentThrowable?.status || 500 }), jsxRuntime_1(OutsideClickHandler, { onOutsideClick: () => bootstrap.setState(currentState => ({ backendThrowable: currentState.backendThrowable.slice(1) })), children: jsxRuntime_1("div", { className: styles.centeredContainer, children: Object.keys(currentThrowable).map((key, index) => {
1412
+ var BackendThrowable = (props) => {
1413
+ const { instance } = props;
1414
+ const currentThrowable = instance.state.backendThrowable[0];
1415
+ console.log([instance.state.backendThrowable, currentThrowable]);
1416
+ return jsxRuntime_2("div", { className: styles.maintenanceHero, children: [jsxRuntime_1("h1", { className: styles.httpStatusCode, children: currentThrowable?.status || 500 }), jsxRuntime_1(OutsideClickHandler, { onOutsideClick: () => instance.setState(currentState => ({ backendThrowable: currentState.backendThrowable.slice(1) })), children: jsxRuntime_1("div", { className: styles.centeredContainer, children: Object.keys(currentThrowable).map((key, index) => {
1417
1417
  const valueIsString = typeof currentThrowable[key] === 'string';
1418
1418
  const valueIsCode = 'THROWN NEAR' === key;
1419
1419
  return jsxRuntime_2("div", { children: [jsxRuntime_2("div", { className: styles.errorTextGeneral, children: [" > ", jsxRuntime_1("span", { className: styles.errorKeys, children: key }), ":", valueIsString
@@ -3922,14 +3922,14 @@ function Popup({ open = true, handleClose, children, maxWidth, }) {
3922
3922
  const isProduction = window.location.host.split(".")[0] === "www";
3923
3923
 
3924
3924
  function addAlert(props) {
3925
- CarbonReact.instance.setState(previousState => ({
3925
+ props.instance.setState(previousState => ({
3926
3926
  alertsWaiting: previousState.alertsWaiting.length === 0
3927
3927
  ? [props]
3928
3928
  : [...previousState.alertsWaiting, props]
3929
3929
  }));
3930
3930
  }
3931
- function Alert() {
3932
- const { alertsWaiting, backendThrowable } = CarbonReact.instance.state;
3931
+ function Alert({ instance }) {
3932
+ const { alertsWaiting, backendThrowable } = instance.state;
3933
3933
  let alert = undefined;
3934
3934
  const alertWaiting = alertsWaiting.length + backendThrowable.length;
3935
3935
  if (backendThrowable.length !== 0) {
@@ -3944,8 +3944,9 @@ function Alert() {
3944
3944
  color: 'primary',
3945
3945
  });
3946
3946
  }
3947
- const backendThrowable = CarbonReact.instance.state.backendThrowable[0];
3947
+ const backendThrowable = instance.state.backendThrowable[0];
3948
3948
  alert = {
3949
+ instance: instance,
3949
3950
  title: "Oh no! An issue occurred!",
3950
3951
  text: backendThrowable?.['DropInGaming\\PHP\\Errors\\DropException'] ?? 'An unknown issue occurred. Please try again.',
3951
3952
  timeout: 0,
@@ -3956,7 +3957,7 @@ function Alert() {
3956
3957
  backendThrowable: backendThrowable,
3957
3958
  then: (value) => {
3958
3959
  if (value === 'Expand') {
3959
- CarbonReact.instance.setState(previousState => {
3960
+ instance.setState(previousState => {
3960
3961
  let backendThrowable = previousState.backendThrowable.pop();
3961
3962
  if (backendThrowable === undefined) {
3962
3963
  return {
@@ -3970,7 +3971,7 @@ function Alert() {
3970
3971
  });
3971
3972
  }
3972
3973
  else {
3973
- CarbonReact.instance.setState(previousState => ({
3974
+ instance.setState(previousState => ({
3974
3975
  backendThrowable: previousState.backendThrowable.slice(1)
3975
3976
  }));
3976
3977
  }
@@ -3984,15 +3985,14 @@ function Alert() {
3984
3985
  return null;
3985
3986
  }
3986
3987
  const timeout = alert?.timeout || 15000;
3987
- const bootstrap = CarbonReact.instance;
3988
- const dig = getStyles();
3988
+ const styles = getStyles();
3989
3989
  let cancelTimeout = null;
3990
3990
  const handleClose = () => {
3991
3991
  if (null !== cancelTimeout) {
3992
3992
  clearTimeout(cancelTimeout);
3993
3993
  }
3994
3994
  if (alert?.backendThrowable === undefined) {
3995
- bootstrap.setState(previousState => ({
3995
+ instance.setState(previousState => ({
3996
3996
  alertsWaiting: previousState.alertsWaiting.slice(1)
3997
3997
  }));
3998
3998
  }
@@ -4006,25 +4006,26 @@ function Alert() {
4006
4006
  handleClose();
4007
4007
  }, timeout);
4008
4008
  }
4009
- return jsxRuntime_1(Popup, { handleClose: handleClose, children: jsxRuntime_2("div", { className: classNames("model-content", dig.rounded0, dig.border0), style: {
4009
+ return jsxRuntime_1(Popup, { handleClose: handleClose, children: jsxRuntime_2("div", { className: classNames("model-content", styles.rounded0, styles.border0), style: {
4010
4010
  maxWidth: '75vw',
4011
4011
  maxHeight: '75vh',
4012
- }, children: [jsxRuntime_2("div", { className: classNames(dig.modalHeader, dig.rounded0, dig.border0, {
4012
+ }, children: [jsxRuntime_2("div", { className: classNames(styles.modalHeader, styles.rounded0, styles.border0, {
4013
4013
  // icon?: "warning" | "error" | "success" | "info" | "question"
4014
- [dig.bg_primary]: "info" === alert.icon || alert.icon === undefined || alert.icon === null,
4015
- [dig.bg_success]: "success" === alert.icon,
4016
- [dig.bg_warning]: "warning" === alert.icon,
4017
- [dig.bg_danger]: "error" === alert.icon, // TODO - change to red
4018
- [dig.bgPrimary]: "question" === alert.icon,
4019
- }), children: [jsxRuntime_2("h3", { className: classNames(dig.modalTitle, dig.textDark), id: "staticBackdropLabel", children: ["#", alertWaiting, " ", alert.title] }), jsxRuntime_1("div", { onClick: handleClose, children: jsxRuntime_1(FontAwesomeIcon, { icon: faClose, size: 'xl' }) })] }), jsxRuntime_1("div", { className: classNames(dig.modalBody, dig.border0, dig.textWhite), children: jsxRuntime_2("div", { className: dig.textCenter, children: [alert.text, alert.component] }) }), undefined !== alert.buttons &&
4020
- jsxRuntime_2("div", { className: classNames(dig.modalFooter, dig.border0, dig.rounded0), children: [alert.footerText && jsxRuntime_1("div", { className: classNames(dig.textCenter, dig.textWhite), children: alert.footerText }), alert.buttons?.map((button, index) => {
4021
- return jsxRuntime_1("button", { className: classNames(dig.btn, dig.btnLg, {
4014
+ [styles.bg_primary]: "info" === alert.icon || alert.icon === undefined || alert.icon === null,
4015
+ [styles.bg_success]: "success" === alert.icon,
4016
+ [styles.bg_warning]: "warning" === alert.icon,
4017
+ [styles.bg_danger]: "error" === alert.icon, // TODO - change to red
4018
+ [styles.bgPrimary]: "question" === alert.icon,
4019
+ }), children: [jsxRuntime_2("h3", { className: classNames(styles.modalTitle, styles.textDark), id: "staticBackdropLabel", children: ["#", alertWaiting, " ", alert.title] }), jsxRuntime_1("div", { onClick: handleClose, children: jsxRuntime_1(FontAwesomeIcon, { icon: faClose, size: 'xl' }) })] }), jsxRuntime_1("div", { className: classNames(styles.modalBody, styles.border0, styles.textWhite), children: jsxRuntime_2("div", { className: styles.textCenter, children: [alert.text, alert.component] }) }), undefined !== alert.buttons &&
4020
+ jsxRuntime_2("div", { className: classNames(styles.modalFooter, styles.border0, styles.rounded0), children: [alert.footerText &&
4021
+ jsxRuntime_1("div", { className: classNames(styles.textCenter, styles.textWhite), children: alert.footerText }), alert.buttons?.map((button, index) => {
4022
+ return jsxRuntime_1("button", { className: classNames(styles.btn, styles.btnLg, {
4022
4023
  // todo - color: "default" | "primary" | "secondary" | "inherit" | "danger" | "info" | "success" | "warning" | undefined,
4023
- [dig.bg_success]: "success" === button.color,
4024
- [dig.bg_danger]: "danger" === button.color,
4025
- [dig.bg_primary]: "primary" === button.color,
4026
- [dig.bg_warning]: "warning" === button.color,
4027
- }, "btn-Yes", dig.rounded0), onClick: () => {
4024
+ [styles.bg_success]: "success" === button.color,
4025
+ [styles.bg_danger]: "danger" === button.color,
4026
+ [styles.bg_primary]: "primary" === button.color,
4027
+ [styles.bg_warning]: "warning" === button.color,
4028
+ }, "btn-Yes", styles.rounded0), onClick: () => {
4028
4029
  handleClose();
4029
4030
  alert?.then?.(button.value ?? button.text);
4030
4031
  }, children: button.text }, index);
@@ -4062,14 +4063,16 @@ const useEffectOnce = (effect) => {
4062
4063
  * @function connect
4063
4064
  * This function establishes a connection with the websocket and also ensures constant reconnection if connection closes
4064
4065
  **/
4065
- function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url = 'ws' + (window.location.protocol === 'https:' ? 's' : '') + '://' + window.location.host + '/carbonorm/websocket', timeoutSeconds = 250, heartbeatSeconds = 60 } = {}) {
4066
- const { websocket } = CarbonReact.instance.state;
4066
+ function initiateWebsocket(props) {
4067
+ let { instance, TABLES = undefined, WsLiveUpdates = undefined, url = 'ws' + (window.location.protocol === 'https:' ? 's' : '') + '://' + window.location.host + '/carbonorm/websocket', timeoutSeconds = 250, heartbeatSeconds = 60 } = props;
4068
+ const { websocket } = instance.state;
4067
4069
  if (!("WebSocket" in window)) {
4068
4070
  // todo - store that this has been shown in the state
4069
4071
  addAlert({
4070
4072
  title: 'Browser does not support websockets, live updates will fail. You may need to refresh the page to see the newest content.',
4071
4073
  text: 'Please use a modern browser.',
4072
4074
  icon: 'warning',
4075
+ instance
4073
4076
  });
4074
4077
  }
4075
4078
  if (false === (undefined === websocket || null === websocket)) {
@@ -4078,14 +4081,14 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
4078
4081
  let connectInterval;
4079
4082
  const connection = new WebSocket(url);
4080
4083
  console.log("Connecting websocket url", url);
4081
- CarbonReact.instance.setState({
4084
+ instance.setState({
4082
4085
  websocket: connection
4083
4086
  }, () => {
4084
4087
  connection.onopen = () => {
4085
4088
  console.log('WebSocket Client Connected To :: ' + url);
4086
4089
  clearTimeout(connectInterval); // clear Interval on open of websocket connection
4087
4090
  function heartbeat() {
4088
- const { websocket } = CarbonReact.instance.state;
4091
+ const { websocket } = instance.state;
4089
4092
  if (!websocket)
4090
4093
  return;
4091
4094
  if (websocket.readyState !== 1)
@@ -4100,7 +4103,7 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
4100
4103
  if (message.data === 'pong') {
4101
4104
  return;
4102
4105
  }
4103
- CarbonReact.instance.setState((prevState) => ({
4106
+ instance.setState((prevState) => ({
4104
4107
  websocketEvents: prevState.websocketEvents.concat(message),
4105
4108
  websocketData: prevState.websocketData.concat(parsedData), // JSON.parse no good - base64?
4106
4109
  }), () => {
@@ -4124,7 +4127,7 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
4124
4127
  }
4125
4128
  console.log('todo - going to impl REST', TABLE_NAME, METHOD, REQUEST_PRIMARY_KEY, parsedData?.REST);
4126
4129
  const TABLE_NAME_SHORT = TABLE_NAME.substring(TABLE_PREFIX.length);
4127
- const currentCache = CarbonReact.instance.state[TABLE_NAME_SHORT];
4130
+ const currentCache = instance.state[TABLE_NAME_SHORT];
4128
4131
  // just because we have a websocket update, doesn't mean we need the update
4129
4132
  // check to see if the primary key is in the current cache
4130
4133
  const c6Table = TABLES[TABLE_NAME_SHORT] ?? null;
@@ -4161,7 +4164,7 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
4161
4164
  }
4162
4165
  });
4163
4166
  };
4164
- window.addEventListener("focus", () => initiateWebsocket());
4167
+ window.addEventListener("focus", () => initiateWebsocket(props));
4165
4168
  // websocket onclose event listener
4166
4169
  connection.addEventListener('close', event => {
4167
4170
  let reason;
@@ -4170,7 +4173,7 @@ function initiateWebsocket({ TABLES = undefined, WsLiveUpdates = undefined, url
4170
4173
  const retrySeconds = Math.min(5000, (timeoutSeconds + timeoutSeconds) * 1000);
4171
4174
  timeoutSeconds = retrySeconds;
4172
4175
  console.log(`WebSocket reconnect will be attempted in ${retrySeconds} second(s).`);
4173
- connectInterval = setTimeout(() => initiateWebsocket(), retrySeconds);
4176
+ connectInterval = setTimeout(() => initiateWebsocket(props), retrySeconds);
4174
4177
  };
4175
4178
  // See https://www.rfc-editor.org/rfc/rfc6455#section-7.4.1
4176
4179
  switch (event.code) {
@@ -4234,6 +4237,106 @@ function CarbonWebSocket (props) {
4234
4237
  return null;
4235
4238
  }
4236
4239
 
4240
+ var eUpdateInsertMethod;
4241
+ (function (eUpdateInsertMethod) {
4242
+ eUpdateInsertMethod[eUpdateInsertMethod["REPLACE"] = 0] = "REPLACE";
4243
+ eUpdateInsertMethod[eUpdateInsertMethod["FIRST"] = 1] = "FIRST";
4244
+ eUpdateInsertMethod[eUpdateInsertMethod["LAST"] = 2] = "LAST";
4245
+ })(eUpdateInsertMethod || (eUpdateInsertMethod = {}));
4246
+ /**
4247
+ * Updates or inserts objects in a stateful array, merging new data with existing objects.
4248
+ * @param instance - The React component instance.
4249
+ * @param dataOrCallback - Array of objects or a callback function returning an array of objects.
4250
+ * @param stateKey - The key in the state where the data array is stored.
4251
+ * @param uniqueObjectId - The unique identifier(s) for objects, typically the primary key of the table.
4252
+ * @param insertUpdateOrder - The order in which new data should be inserted/updated.
4253
+ * @param callback - Optional callback function to run after state update.
4254
+ */
4255
+ function updateRestfulObjectArrays({ instance, dataOrCallback, stateKey, uniqueObjectId, insertUpdateOrder = eUpdateInsertMethod.LAST, callback, }) {
4256
+ const uniqueObjectIds = Array.isArray(uniqueObjectId) ? uniqueObjectId : [uniqueObjectId];
4257
+ instance.setState((previousBootstrapState, props) => {
4258
+ let newOrReplacementData = [];
4259
+ if (Array.isArray(dataOrCallback)) {
4260
+ newOrReplacementData = dataOrCallback;
4261
+ }
4262
+ else if (typeof dataOrCallback === "function") {
4263
+ newOrReplacementData = dataOrCallback(previousBootstrapState, props);
4264
+ }
4265
+ else {
4266
+ throw new Error("The dataOrCallback parameter must be an array or function");
4267
+ }
4268
+ if (newOrReplacementData === null) {
4269
+ return null;
4270
+ }
4271
+ const findUniqueObjectIds = (item, value) => {
4272
+ return uniqueObjectIds.every((id) => item[id] === value[id]);
4273
+ };
4274
+ const previousStateProperty = previousBootstrapState[stateKey] ?? [];
4275
+ let updatedData = newOrReplacementData.map((value) => {
4276
+ const existingObject = previousStateProperty?.find((item) => findUniqueObjectIds(item, value)) || {};
4277
+ return { ...existingObject, ...value };
4278
+ });
4279
+ const filterOutUpdated = (array) => {
4280
+ return array?.filter((item) => !updatedData.some((value) => findUniqueObjectIds(item, value))) ?? [];
4281
+ };
4282
+ let newState = {};
4283
+ switch (insertUpdateOrder) {
4284
+ case eUpdateInsertMethod.LAST:
4285
+ newState[stateKey] = [
4286
+ ...filterOutUpdated(previousStateProperty),
4287
+ ...updatedData,
4288
+ ];
4289
+ break;
4290
+ case eUpdateInsertMethod.FIRST:
4291
+ newState[stateKey] = [
4292
+ ...updatedData,
4293
+ ...filterOutUpdated(previousStateProperty),
4294
+ ];
4295
+ break;
4296
+ case eUpdateInsertMethod.REPLACE:
4297
+ newState[stateKey] = [
4298
+ ...(previousStateProperty?.map((oldObject) => {
4299
+ const index = updatedData.findIndex((item) => findUniqueObjectIds(item, oldObject));
4300
+ if (index !== -1) {
4301
+ return updatedData.splice(index, 1)[0];
4302
+ }
4303
+ return oldObject;
4304
+ }) ?? []),
4305
+ ...updatedData,
4306
+ ];
4307
+ break;
4308
+ default:
4309
+ throw new Error("The insertUpdateOrder (eUpdateInsertMethod) was not implemented");
4310
+ }
4311
+ return newState;
4312
+ }, callback);
4313
+ }
4314
+
4315
+ function deleteRestfulObjectArrays({ instance, dataOrCallback, stateKey, uniqueObjectId, callback }) {
4316
+ const uniqueObjectIds = Array.isArray(uniqueObjectId) ? uniqueObjectId : [uniqueObjectId];
4317
+ instance.setState((previousBootstrapState, props) => {
4318
+ let newOrReplacementData = [];
4319
+ if (Array.isArray(dataOrCallback)) {
4320
+ newOrReplacementData = dataOrCallback;
4321
+ }
4322
+ else if (typeof dataOrCallback === 'function') {
4323
+ const callbackReturn = dataOrCallback(previousBootstrapState, props);
4324
+ if (callbackReturn === null) {
4325
+ return null; // No updates needed (noop)
4326
+ }
4327
+ newOrReplacementData = callbackReturn;
4328
+ }
4329
+ else {
4330
+ throw new Error('The dataOrCallback parameter was not an array or function');
4331
+ }
4332
+ const previousStateProperty = previousBootstrapState[stateKey];
4333
+ const updatedStateProperty = previousStateProperty?.filter(item => !newOrReplacementData.some(value => uniqueObjectIds.every(uniqueId => value[uniqueId] === item[uniqueId]))) ?? [];
4334
+ return {
4335
+ [stateKey]: updatedStateProperty
4336
+ };
4337
+ }, callback);
4338
+ }
4339
+
4237
4340
  const initialRequiredCarbonORMState = {
4238
4341
  alertsWaiting: [],
4239
4342
  backendThrowable: [],
@@ -4254,27 +4357,32 @@ function isJsonString(str) {
4254
4357
  }
4255
4358
  return true;
4256
4359
  }
4257
- // Create a context
4258
4360
  const persistentStateMap = new Map();
4259
4361
  class CarbonReact extends Component {
4260
4362
  context = createContext(this.state);
4261
4363
  // Private static member
4364
+ // we actually implement this in the constructor todo - test this
4262
4365
  static instance;
4263
- static getState() {
4264
- return CarbonReact.instance.state;
4265
- }
4266
- static useContext() {
4267
- return () => useContext(CarbonReact.instance.context);
4268
- }
4269
- protected;
4366
+ target;
4367
+ updateRestfulObjectArrays = (rest) => updateRestfulObjectArrays({
4368
+ instance: this,
4369
+ ...rest
4370
+ });
4371
+ deleteRestfulObjectArrays = (rest) => deleteRestfulObjectArrays({
4372
+ instance: this,
4373
+ ...rest
4374
+ });
4270
4375
  static lastLocation = window.location.pathname;
4271
4376
  // @link https://github.com/welldone-software/why-did-you-render
4272
4377
  // noinspection JSUnusedGlobalSymbols
4273
4378
  static whyDidYouRender = true;
4274
4379
  constructor(props) {
4275
4380
  super(props);
4381
+ this.target = new.target;
4276
4382
  console.log('CarbonORM TSX CONSTRUCTOR');
4277
- Object.assign(this, {
4383
+ // this is the magic that allows each class that's extends this to have a static instance - a singleton pattern
4384
+ // new.target is a meta-property introduced in ES6 that references the constructor that was directly invoked with the new keyword.
4385
+ Object.assign(new.target, {
4278
4386
  instance: this
4279
4387
  });
4280
4388
  if (this.props.instanceId && persistentStateMap.has(this.props.instanceId)) {
@@ -4319,11 +4427,11 @@ class CarbonReact extends Component {
4319
4427
  console.log('%c color (' + colorHex + ')', 'color: ' + colorHex);
4320
4428
  const nest = jsxRuntime_1(Nest, { position: 'fixed', backgroundColor: '', color: hexToRgb(colorHex), count: 100 });
4321
4429
  if (this.state.backendThrowable.length > 0) {
4322
- return jsxRuntime_2(jsxRuntime_3, { children: [nest, jsxRuntime_1(BackendThrowable, {})] });
4430
+ return jsxRuntime_2(jsxRuntime_3, { children: [nest, jsxRuntime_1(BackendThrowable, { instance: CarbonReact.instance })] });
4323
4431
  }
4324
4432
  const Context = this.context.Provider;
4325
4433
  return jsxRuntime_2(jsxRuntime_3, { children: [jsxRuntime_1(GlobalHistory, {}), this.props.websocket &&
4326
- jsxRuntime_1(CarbonWebSocket, { ...(true === this.props.websocket ? {} : this.props.websocket) }), jsxRuntime_1(Context, { value: this.state, children: this.props.children }), jsxRuntime_1(ToastContainer, {})] });
4434
+ jsxRuntime_1(CarbonWebSocket, { ...(true === this.props.websocket ? {} : this.props.websocket), instance: CarbonReact.instance }), jsxRuntime_1(Context, { value: this.state, children: this.props.children }), jsxRuntime_1(ToastContainer, {})] });
4327
4435
  }
4328
4436
  }
4329
4437
 
@@ -4382,44 +4490,6 @@ function addValidSQL$1 (sql) {
4382
4490
  addValidSQL.push({ [expect.getState().currentTestName.replaceAll(" ", "_").toLowerCase()]: sql });
4383
4491
  }
4384
4492
 
4385
- //ObjectType, UniqueIdType extends keyof ObjectType
4386
- // @link https://www.typescriptlang.org/docs/handbook/2/mapped-types.html
4387
- function deleteRestfulObjectArrays(dataOrCallback, stateKey, uniqueObjectId, callback) {
4388
- const uniqueObjectIds = uniqueObjectId instanceof Array ? uniqueObjectId : [uniqueObjectId];
4389
- return CarbonReact.instance.setState((previousBootstrapState, props) => {
4390
- let newOrReplacementData = [];
4391
- if (dataOrCallback instanceof Array) {
4392
- newOrReplacementData = dataOrCallback;
4393
- }
4394
- else if (dataOrCallback instanceof Function) {
4395
- let callbackReturn = dataOrCallback(previousBootstrapState, props);
4396
- if (null === callbackReturn) {
4397
- return;
4398
- }
4399
- newOrReplacementData = callbackReturn;
4400
- }
4401
- else {
4402
- throw Error('The dataOrCallback parameter was not an array or function');
4403
- }
4404
- const previousStateProperty = previousBootstrapState[stateKey];
4405
- return {
4406
- [stateKey]: [
4407
- ...previousStateProperty?.filter(item => false === (newOrReplacementData?.find(value => {
4408
- let isMatch = true;
4409
- uniqueObjectIds.find(uniqueObjectId => {
4410
- if (value[uniqueObjectId] !== item[uniqueObjectId]) {
4411
- isMatch = false;
4412
- return true;
4413
- }
4414
- return false;
4415
- });
4416
- return isMatch;
4417
- }) || false)) || []
4418
- ]
4419
- };
4420
- }, callback);
4421
- }
4422
-
4423
4493
  // @link https://stackoverflow.com/questions/31721250/how-to-target-edge-browser-with-javascript
4424
4494
  // Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) \
4425
4495
  // Chrome/107.0.0.0 Safari/537.36 Edg/107.0.1418.26
@@ -4559,89 +4629,6 @@ function setupTests ({ sqlDirectory = './logs/rest/', logsDirectory = './logs/te
4559
4629
  }, 65000);
4560
4630
  }
4561
4631
 
4562
- var eUpdateInsertMethod;
4563
- (function (eUpdateInsertMethod) {
4564
- eUpdateInsertMethod[eUpdateInsertMethod["REPLACE"] = 0] = "REPLACE";
4565
- eUpdateInsertMethod[eUpdateInsertMethod["FIRST"] = 1] = "FIRST";
4566
- eUpdateInsertMethod[eUpdateInsertMethod["LAST"] = 2] = "LAST";
4567
- })(eUpdateInsertMethod || (eUpdateInsertMethod = {}));
4568
- /**
4569
- *
4570
- * merged with existing objects.uniqueObjectId || {}.
4571
- * @param dataOrCallback
4572
- * @param uniqueObjectId - the uniqueObjectId of the object to update; typically the primary key of the table.
4573
- * @param stateKey -
4574
- * @param insertUpdateOrder
4575
- * @param callback - if you want to do something with the updated state, you can pass a callback here. Run as the second
4576
- * parameter of setState.
4577
- */
4578
- function updateRestfulObjectArrays(dataOrCallback, stateKey, uniqueObjectId, insertUpdateOrder = eUpdateInsertMethod.LAST, callback) {
4579
- const uniqueObjectIds = uniqueObjectId instanceof Array ? uniqueObjectId : [uniqueObjectId];
4580
- const bootstrap = CarbonReact.instance;
4581
- return bootstrap.setState((previousBootstrapState, props) => {
4582
- let newOrReplacementData = [];
4583
- if (dataOrCallback instanceof Array) {
4584
- newOrReplacementData = dataOrCallback;
4585
- }
4586
- else if (dataOrCallback instanceof Function) {
4587
- newOrReplacementData = dataOrCallback(previousBootstrapState, props);
4588
- }
4589
- else {
4590
- throw Error('The dataOrCallback parameter was not an array or function');
4591
- }
4592
- const findUniqueObjectIds = (item, value) => {
4593
- let isMatch = true;
4594
- uniqueObjectIds.find(uniqueObjectId => {
4595
- if (value[uniqueObjectId] !== item[uniqueObjectId]) {
4596
- isMatch = false;
4597
- return true;
4598
- }
4599
- return false;
4600
- });
4601
- return isMatch;
4602
- };
4603
- const previousStateProperty = previousBootstrapState[stateKey];
4604
- let updatedData = newOrReplacementData?.map(value => {
4605
- return {
4606
- ...previousStateProperty?.find(previousValue => findUniqueObjectIds(previousValue, value)) || {},
4607
- ...value
4608
- };
4609
- }) ?? [];
4610
- switch (insertUpdateOrder) {
4611
- default:
4612
- throw Error('The insertUpdateOrder (eUpdateInsertMethod) was not implemented');
4613
- case eUpdateInsertMethod.LAST:
4614
- return {
4615
- [stateKey]: null === newOrReplacementData ? null : [
4616
- ...updatedData,
4617
- ...(previousStateProperty?.filter(item => false === (updatedData?.find(value => findUniqueObjectIds(item, value)) || false)) ?? [])
4618
- ]
4619
- };
4620
- case eUpdateInsertMethod.FIRST:
4621
- return {
4622
- [stateKey]: null === newOrReplacementData ? null : [
4623
- ...(previousStateProperty?.filter(item => false === (updatedData?.find(value => findUniqueObjectIds(item, value)) || false)) ?? []),
4624
- ...updatedData,
4625
- ]
4626
- };
4627
- case eUpdateInsertMethod.REPLACE: {
4628
- return {
4629
- [stateKey]: [
4630
- ...(previousStateProperty?.map(oldObject => {
4631
- const index = updatedData.findIndex(item => findUniqueObjectIds(item, oldObject));
4632
- if (-1 === index) {
4633
- return oldObject;
4634
- }
4635
- return updatedData.splice(index, 1).pop();
4636
- }) ?? []),
4637
- ...updatedData
4638
- ]
4639
- };
4640
- }
4641
- }
4642
- }, callback);
4643
- }
4644
-
4645
4632
  // @link https://stackoverflow.com/questions/6735414/php-data-uri-to-file
4646
4633
  // @link https://www.tutorialspoint.com/convert-image-to-data-uri-with-javascript
4647
4634
  async function toDataURL(src, fileType, callback) {