pict 1.0.392 → 1.0.393
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/pict.js +20 -10
- package/dist/pict.js.map +1 -1
- package/dist/pict.min.js +2 -2
- package/dist/pict.min.js.map +1 -1
- package/package.json +1 -1
- package/source/Pict-Meadow-EntityProvider.js +49 -15
- package/types/source/Pict-Meadow-EntityProvider.d.ts +13 -2
- package/types/source/Pict-Meadow-EntityProvider.d.ts.map +1 -1
- package/dist/indoctrinate_content_staging/Indoctrinate-Catalog-AppData.json +0 -12920
package/dist/pict.js
CHANGED
|
@@ -6270,7 +6270,7 @@ try{if(!global.localStorage)return false;}catch(_){return false;}var val=global.
|
|
|
6270
6270
|
// presumably different callback function.
|
|
6271
6271
|
// This makes sure that own properties are retained, so that
|
|
6272
6272
|
// decorations and such are not lost along the way.
|
|
6273
|
-
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],191:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],192:[function(require,module,exports){module.exports={"name":"pict","version":"1.0.
|
|
6273
|
+
module.exports=wrappy;function wrappy(fn,cb){if(fn&&cb)return wrappy(fn)(cb);if(typeof fn!=='function')throw new TypeError('need wrapper function');Object.keys(fn).forEach(function(k){wrapper[k]=fn[k];});return wrapper;function wrapper(){var args=new Array(arguments.length);for(var i=0;i<args.length;i++){args[i]=arguments[i];}var ret=fn.apply(this,args);var cb=args[args.length-1];if(typeof ret==='function'&&ret!==cb){Object.keys(cb).forEach(function(k){ret[k]=cb[k];});}return ret;}}},{}],191:[function(require,module,exports){module.exports=extend;var hasOwnProperty=Object.prototype.hasOwnProperty;function extend(){var target={};for(var i=0;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;}},{}],192:[function(require,module,exports){module.exports={"name":"pict","version":"1.0.393","description":"Pict browser library.","main":"source/Pict.js","scripts":{"start":"node source/Pict.js","test":"npx quack test","tests":"npx quack test -g","coverage":"npx quack coverage","build":"npx quack build","prepublishOnly":"npx quack build","docker-dev-build":"docker build ./ -f Dockerfile_LUXURYCode -t pict-image:local","docker-dev-run":"docker run -it -d --name pict-dev -p 37447:8080 -p 19506:8086 -v \"$PWD/.config:/home/coder/.config\" -v \"$PWD:/home/coder/pict\" -u \"$(id -u):$(id -g)\" -e \"DOCKER_USER=$USER\" pict-image:local","docker-dev-shell":"docker exec -it pict-dev /bin/bash","lint":"eslint source/**/*.js test/**/*.js","types":"tsc -p ."},"files":["source/","dist/","types/"],"types":"types/source/Pict.d.ts","mocha":{"diff":true,"extension":["js"],"package":"./package.json","reporter":"spec","slow":"75","timeout":"5000","ui":"tdd","watch-files":["source/**/*.js","test/**/*.js"],"watch-ignore":["lib/vendor"]},"repository":{"type":"git","url":"git+https://github.com/fable-retold/pict.git"},"author":"steven velozo <steven@velozo.com>","license":"MIT","bugs":{"url":"https://github.com/fable-retold/pict/issues"},"homepage":"https://github.com/fable-retold/pict#readme","devDependencies":{"@eslint/js":"^9.39.1","@types/jquery":"^3.5.33","@types/sinon":"^17.0.4","eslint":"^9.39.1","globals":"^16.5.0","pict-docuserve":"^1.4.19","quackage":"^1.3.0","sinon":"^20.0.0","typescript":"^5.9.3"},"dependencies":{"cachetrax":"^1.0.6","fable":"^3.1.79","pict-application":"^1.0.34","pict-provider":"^1.0.13","pict-template":"^1.0.15","pict-view":"^1.0.68"}};},{}],193:[function(require,module,exports){// This assumes Pict has been required in the browser. Delcare these as globals so linter can do its job.
|
|
6274
6274
|
/* global Pict, _Pict: writeable *//**
|
|
6275
6275
|
* Simple function to load a pict Application
|
|
6276
6276
|
*
|
|
@@ -6558,15 +6558,23 @@ for(let i=0;i<3;i++){const tmpHave=isNaN(tmpParts[i])?0:tmpParts[i];const tmpNee
|
|
|
6558
6558
|
* @return {void}
|
|
6559
6559
|
*/resolveEntityQuerySupport(pEntity,pURLPrefix,fCallback){if(!this.useQueryEndpoint){return fCallback(null,false);}const tmpKey=this._capabilityKey(pEntity,pURLPrefix);if(tmpKey in this.endpointCapabilityCache){return fCallback(null,this.endpointCapabilityCache[tmpKey].SupportsQuery);}if(this.endpointCapabilityInflight[tmpKey]){this.endpointCapabilityInflight[tmpKey].push(fCallback);return;}this.endpointCapabilityInflight[tmpKey]=[fCallback];/** @type {Record<string, any>} */let tmpOptions={url:`${pURLPrefix||this.options.urlPrefix}${pEntity}/Schema`};tmpOptions=this.prepareRequestOptions(tmpOptions);this.restClient.getJSON(tmpOptions,(pError,pResponse,pBody)=>{let tmpSupportsQuery=false;if(!pError){try{tmpSupportsQuery=this.evaluateQueryEndpointSupport(pBody);}catch(pEvaluateError){tmpSupportsQuery=false;}// Only cache on a clean probe; transient errors stay re-probeable.
|
|
6560
6560
|
this.endpointCapabilityCache[tmpKey]={SupportsQuery:tmpSupportsQuery,Metadata:pBody&&pBody.RetoldMetadata||null};}else{this.log.warn(`EntityProvider capability probe for [${pEntity}] failed; falling back to GET reads: ${pError}`);}const tmpCallbacks=this.endpointCapabilityInflight[tmpKey];delete this.endpointCapabilityInflight[tmpKey];for(let i=0;i<tmpCallbacks.length;i++){tmpCallbacks[i](null,tmpSupportsQuery);}});}/**
|
|
6561
|
+
* Normalize a step Projection into lite-read shaping. `Lite` and
|
|
6562
|
+
* `LiteExtended` both map to a lite read; `LiteExtended` with no
|
|
6563
|
+
* ExtraColumns degrades to a plain Lite read.
|
|
6564
|
+
*
|
|
6565
|
+
* @param {Record<string, any>} [pProjection] - Optional { Mode:'Lite'|'LiteExtended', ExtraColumns:[...] }.
|
|
6566
|
+
* @return {{ ExtraColumns: string|null }|null} Lite-read shaping, or null for a full read.
|
|
6567
|
+
*/_resolveLiteProjection(pProjection){if(!pProjection||pProjection.Mode!=='Lite'&&pProjection.Mode!=='LiteExtended'){return null;}const tmpExtraColumns=Array.isArray(pProjection.ExtraColumns)&&pProjection.ExtraColumns.length>0?pProjection.ExtraColumns.join(','):null;return{ExtraColumns:tmpExtraColumns};}/**
|
|
6561
6568
|
* Build the POST /:Entity/Query request body for a filtered read.
|
|
6562
6569
|
*
|
|
6563
6570
|
* @param {string} pMeadowFilterExpression - The meadow filter string (may be empty).
|
|
6564
6571
|
* @param {number|null} [pBegin] - Pagination start cursor.
|
|
6565
6572
|
* @param {number|null} [pCap] - Pagination page size.
|
|
6566
|
-
* @param {Record<string, any>} [pProjection] - Optional { Mode:'LiteExtended', ExtraColumns:[...] }.
|
|
6573
|
+
* @param {Record<string, any>} [pProjection] - Optional { Mode:'Lite'|'LiteExtended', ExtraColumns:[...] }.
|
|
6567
6574
|
* @return {Record<string, any>} The request body envelope.
|
|
6568
|
-
*/_buildQueryReadBody(pMeadowFilterExpression,pBegin,pCap,pProjection){/** @type {Record<string, any>} */const tmpBody={};if(pMeadowFilterExpression){tmpBody.Filter=pMeadowFilterExpression;}if(typeof pBegin==='number'){tmpBody.Begin=pBegin;}if(typeof pCap==='number'){tmpBody.Cap=pCap;}
|
|
6569
|
-
|
|
6575
|
+
*/_buildQueryReadBody(pMeadowFilterExpression,pBegin,pCap,pProjection){/** @type {Record<string, any>} */const tmpBody={};if(pMeadowFilterExpression){tmpBody.Filter=pMeadowFilterExpression;}if(typeof pBegin==='number'){tmpBody.Begin=pBegin;}if(typeof pCap==='number'){tmpBody.Cap=pCap;}const tmpLiteProjection=this._resolveLiteProjection(pProjection);if(tmpLiteProjection){// Lite/LiteExtended GET reads map to a Lite Query read; ExtraColumns
|
|
6576
|
+
// carries the LiteExtended column list when present.
|
|
6577
|
+
tmpBody.Lite=true;if(tmpLiteProjection.ExtraColumns){tmpBody.ExtraColumns=tmpLiteProjection.ExtraColumns;}}return tmpBody;}/**
|
|
6570
6578
|
* Read a page of an entity set, using POST /:Entity/Query when supported and
|
|
6571
6579
|
* falling back to the legacy GET read otherwise. The callback mirrors
|
|
6572
6580
|
* restClient.getJSON exactly: (pError, pResponse, pBody).
|
|
@@ -6578,7 +6586,7 @@ tmpBody.Lite=true;tmpBody.ExtraColumns=pProjection.ExtraColumns.join(',');}retur
|
|
|
6578
6586
|
* @param {Record<string, any>} pReadOptions - { SupportsQuery, URLPrefix, Postfix, Projection }.
|
|
6579
6587
|
* @param {(pError: Error|null, pResponse: any, pBody: any) => void} fCallback - Completion callback.
|
|
6580
6588
|
* @return {void}
|
|
6581
|
-
*/_readEntityPage(pEntity,pMeadowFilterExpression,pBegin,pCap,pReadOptions,fCallback){const tmpURLPrefix=pReadOptions&&pReadOptions.URLPrefix||this.options.urlPrefix;const tmpPostfix=pReadOptions&&pReadOptions.Postfix||'';const tmpProjection=pReadOptions?pReadOptions.Projection:null;if(pReadOptions&&pReadOptions.SupportsQuery){const tmpRequestOptions={url:`${tmpURLPrefix}${pEntity}s/Query${tmpPostfix}`,body:this._buildQueryReadBody(pMeadowFilterExpression,pBegin,pCap,tmpProjection)};return this.restClient.postJSON(tmpRequestOptions,fCallback);}const tmpFilterStanza=pMeadowFilterExpression?`/FilteredTo/${pMeadowFilterExpression}`:'';const
|
|
6589
|
+
*/_readEntityPage(pEntity,pMeadowFilterExpression,pBegin,pCap,pReadOptions,fCallback){const tmpURLPrefix=pReadOptions&&pReadOptions.URLPrefix||this.options.urlPrefix;const tmpPostfix=pReadOptions&&pReadOptions.Postfix||'';const tmpProjection=pReadOptions?pReadOptions.Projection:null;if(pReadOptions&&pReadOptions.SupportsQuery){const tmpRequestOptions={url:`${tmpURLPrefix}${pEntity}s/Query${tmpPostfix}`,body:this._buildQueryReadBody(pMeadowFilterExpression,pBegin,pCap,tmpProjection)};return this.restClient.postJSON(tmpRequestOptions,fCallback);}const tmpFilterStanza=pMeadowFilterExpression?`/FilteredTo/${pMeadowFilterExpression}`:'';const tmpLiteProjection=this._resolveLiteProjection(tmpProjection);const tmpProjectionStanza=tmpLiteProjection?tmpLiteProjection.ExtraColumns?`/LiteExtended/${tmpLiteProjection.ExtraColumns}`:'/Lite':'';const tmpPageStanza=typeof pBegin==='number'&&typeof pCap==='number'?`/${pBegin}/${pCap}`:'';const tmpURL=`${tmpURLPrefix}${pEntity}s${tmpProjectionStanza}${tmpFilterStanza}${tmpPageStanza}${tmpPostfix}`;return this.restClient.getJSON(tmpURL,fCallback);}/**
|
|
6582
6590
|
* Read the count of an entity set, using POST /:Entity/Query (Count mode)
|
|
6583
6591
|
* when supported and the legacy GET Count otherwise. The callback mirrors
|
|
6584
6592
|
* restClient.getJSON: (pError, pResponse, pBody) where pBody carries .Count.
|
|
@@ -6895,25 +6903,27 @@ else if(tmpColumnName in this.entityColumnTranslations){tmpIDColumnsToCache.push
|
|
|
6895
6903
|
* @param {string} pMeadowFilterExpression - The meadow filter expression to filter the entity set by.
|
|
6896
6904
|
* @param {(pError?: Error, pEntitySet?: Array) => void} fCallback - The callback to call when the request is complete.
|
|
6897
6905
|
* @param {string} [postfix] - Optional, adds a postfix string to all calls made.
|
|
6898
|
-
* @param {Record<string, any>} [pOptions] - Optional, per-call options (e.g. { DownloadPageConcurrency: 1 }).
|
|
6906
|
+
* @param {Record<string, any>} [pOptions] - Optional, per-call options (e.g. { DownloadPageConcurrency: 1, Projection: { Mode: 'LiteExtended', ExtraColumns: [...] } }).
|
|
6899
6907
|
*
|
|
6900
6908
|
* @return {void}
|
|
6901
|
-
*/getEntitySet(pEntity,pMeadowFilterExpression,fCallback){let postfix=arguments.length>3&&arguments[3]!==undefined?arguments[3]:'';let pOptions=arguments.length>4&&arguments[4]!==undefined?arguments[4]:{};const tmpURLPrefix=pOptions.URLPrefix||this.options.urlPrefix;const tmpScope=pOptions&&pOptions.Scope?pOptions.Scope:'';this.initializeCache(pEntity,tmpScope);const tmpCacheKey=this._cacheKey(pEntity,tmpScope);// Resolve transport capability once for the whole read (count + every
|
|
6909
|
+
*/getEntitySet(pEntity,pMeadowFilterExpression,fCallback){let postfix=arguments.length>3&&arguments[3]!==undefined?arguments[3]:'';let pOptions=arguments.length>4&&arguments[4]!==undefined?arguments[4]:{};const tmpURLPrefix=pOptions.URLPrefix||this.options.urlPrefix;const tmpScope=pOptions&&pOptions.Scope?pOptions.Scope:'';const tmpProjection=pOptions&&pOptions.Projection?pOptions.Projection:null;this.initializeCache(pEntity,tmpScope);const tmpCacheKey=this._cacheKey(pEntity,tmpScope);// Resolve transport capability once for the whole read (count + every
|
|
6902
6910
|
// page share the same SupportsQuery flag). The legacy GET reads embed the
|
|
6903
6911
|
// filter (and any large IN-list) in the URI, which is exactly the long-URI
|
|
6904
6912
|
// failure POST /:Entity/Query avoids when the server supports it.
|
|
6905
|
-
this.resolveEntityQuerySupport(pEntity,tmpURLPrefix,(pSupportError,pSupportsQuery)=>{const tmpReadOptions={SupportsQuery:pSupportsQuery,URLPrefix:tmpURLPrefix,Postfix:postfix||''};// Discard anything from the cache that has expired or is over size.
|
|
6913
|
+
this.resolveEntityQuerySupport(pEntity,tmpURLPrefix,(pSupportError,pSupportsQuery)=>{const tmpReadOptions={SupportsQuery:pSupportsQuery,URLPrefix:tmpURLPrefix,Postfix:postfix||'',Projection:tmpProjection};// Discard anything from the cache that has expired or is over size.
|
|
6906
6914
|
this.recordSetCache[tmpCacheKey].prune(function(){let tmpPossibleRecords=this.recordSetCache[tmpCacheKey].read(pMeadowFilterExpression);if(tmpPossibleRecords){return fCallback(null,tmpPossibleRecords);}if(pOptions.NoCount){// Lazily load until we hit a not full page rather than using couns.
|
|
6907
6915
|
// Does not respect parallelization.
|
|
6908
6916
|
const pageSize=250;let page=0;let returnSet=[];const recursiveCallback=(pDownloadError,pDownloadResponse,pDownloadBody)=>{// A transport-level failure (e.g. connection reset, expired TLS
|
|
6909
6917
|
// cert) calls back with no response, so guard every pDownloadResponse
|
|
6910
6918
|
// deref and surface the underlying error rather than throwing a
|
|
6911
6919
|
// TypeError on the missing statusCode.
|
|
6912
|
-
if(pDownloadError||pDownloadResponse&&pDownloadResponse.statusCode&&pDownloadResponse.statusCode>=400||!Array.isArray(pDownloadBody)){const tmpStatusCode=pDownloadResponse?pDownloadResponse.statusCode:'no response';const tmpStatusDetail=pDownloadError?pDownloadError.message||pDownloadError:pDownloadResponse?pDownloadResponse.statusMessage:'';this.log.error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}]: ${tmpStatusCode} ${tmpStatusDetail}`);return fCallback(pDownloadError||new Error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}]: ${tmpStatusCode} ${JSON.stringify(pDownloadBody||{})}`),[]);}returnSet=returnSet.concat(pDownloadBody);if((pDownloadBody===null||pDownloadBody===void 0?void 0:pDownloadBody.length)<pageSize){
|
|
6920
|
+
if(pDownloadError||pDownloadResponse&&pDownloadResponse.statusCode&&pDownloadResponse.statusCode>=400||!Array.isArray(pDownloadBody)){const tmpStatusCode=pDownloadResponse?pDownloadResponse.statusCode:'no response';const tmpStatusDetail=pDownloadError?pDownloadError.message||pDownloadError:pDownloadResponse?pDownloadResponse.statusMessage:'';this.log.error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}]: ${tmpStatusCode} ${tmpStatusDetail}`);return fCallback(pDownloadError||new Error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}]: ${tmpStatusCode} ${JSON.stringify(pDownloadBody||{})}`),[]);}returnSet=returnSet.concat(pDownloadBody);if((pDownloadBody===null||pDownloadBody===void 0?void 0:pDownloadBody.length)<pageSize){// Do not cache projected (partial) records — see getEntitySetPage.
|
|
6921
|
+
if(!tmpProjection){this.recordSetCache[tmpCacheKey].put(returnSet,pMeadowFilterExpression);this.cacheIndividualEntityRecords(pEntity,returnSet,tmpScope);}fCallback(null,returnSet);}else{page+=1;this._readEntityPage(pEntity,pMeadowFilterExpression,page*pageSize,pageSize,tmpReadOptions,recursiveCallback);}};return this._readEntityPage(pEntity,pMeadowFilterExpression,page*pageSize,pageSize,tmpReadOptions,recursiveCallback);}return this.getEntitySetRecordCount(pEntity,pMeadowFilterExpression,(pRecordCountError,pRecordCount)=>{if(pRecordCountError){return fCallback(pRecordCountError);}let tmpRecordCount=pRecordCount;if(isNaN(pRecordCount)){this.log.error(`Entity count did not return a number for [${pEntity}] filtered to [${pMeadowFilterExpression}]... something is fatally wrong from the server accessed in getEntitySet call.`);return fCallback(new Error('Entity count did not return a number in getEntitySet.'));}let tmpDownloadBatchSize=this.options.downloadBatchSize;const tmpPageCount=Math.ceil(tmpRecordCount/tmpDownloadBatchSize);// Build an indexed array of page descriptors to preserve ordering
|
|
6913
6922
|
const tmpPages=[];for(let i=0;i<tmpPageCount;i++){tmpPages.push({Index:i,Begin:i*tmpDownloadBatchSize,Records:null});}// Fetch pages concurrently and reassemble in order.
|
|
6914
6923
|
// Per-call DownloadPageConcurrency overrides the provider-level default.
|
|
6915
6924
|
const tmpPageConcurrency=typeof pOptions.DownloadPageConcurrency==='number'?pOptions.DownloadPageConcurrency:typeof this.options.downloadPageConcurrency==='number'?this.options.downloadPageConcurrency:4;this.fable.Utility.eachLimit(tmpPages,tmpPageConcurrency,(pPage,fDownloadCallback)=>{this._readEntityPage(pEntity,pMeadowFilterExpression,pPage.Begin,tmpDownloadBatchSize,tmpReadOptions,(pDownloadError,pDownloadResponse,pDownloadBody)=>{if(pDownloadResponse&&pDownloadResponse.statusCode&&pDownloadResponse.statusCode>=400){this.log.error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}] [${pPage.Begin}/${tmpDownloadBatchSize}]: ${pDownloadResponse.statusCode} ${pDownloadResponse.statusMessage}`);return fDownloadCallback(new Error(`Error getting entity set of [${pEntity}] filtered to [${pMeadowFilterExpression}] [${pPage.Begin}/${tmpDownloadBatchSize}]: ${pDownloadResponse.statusCode} ${JSON.stringify(pDownloadBody||{})}`));}if(Array.isArray(pDownloadBody)){pPage.Records=pDownloadBody;}return fDownloadCallback(pDownloadError);});},pFullDownloadError=>{// Reassemble pages in index order to maintain consistent ordering
|
|
6916
|
-
let tmpEntitySet=[];for(let i=0;i<tmpPages.length;i++){if(Array.isArray(tmpPages[i].Records)){tmpEntitySet=tmpEntitySet.concat(tmpPages[i].Records);}}
|
|
6925
|
+
let tmpEntitySet=[];for(let i=0;i<tmpPages.length;i++){if(Array.isArray(tmpPages[i].Records)){tmpEntitySet=tmpEntitySet.concat(tmpPages[i].Records);}}// Do not cache projected (partial) records — see getEntitySetPage.
|
|
6926
|
+
if(!tmpProjection){if(tmpEntitySet){this.recordSetCache[tmpCacheKey].put(tmpEntitySet,pMeadowFilterExpression);}this.cacheIndividualEntityRecords(pEntity,tmpEntitySet,tmpScope);}return fCallback(pFullDownloadError,tmpEntitySet);});},postfix,pOptions.URLPrefix);}.bind(this));});}////////////////////////////////////////////////////////////////////////////////
|
|
6917
6927
|
// Entity Creation and Update Methods
|
|
6918
6928
|
/**
|
|
6919
6929
|
* @param {string} pEntityType - The type of the entity to format the URL for.
|